Appearance
使用Python调用Solidity合约
这里使用的合约来自于这里中的一个布尔可满性证明电路生成的Verify合约,于Sepolia 0xbEA8E0F363b1B8469f7971ED157Ec262232D293e部署。
1. 安装依赖
bash
pip install web3 eth-account2. 准备一个RPC节点
这里使用GetBlock
3. Python代码示例
CAUTION
💀孩子们注意资金账户和测试账户要分开
abi
json
[
{
"inputs": [
{
"internalType": "uint256[24]",
"name": "_proof",
"type": "uint256[24]"
},
{
"internalType": "uint256[1]",
"name": "_pubSignals",
"type": "uint256[1]"
}
],
"name": "verifyProof",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
]proof & public signals
json
{
"A": [
"21860314311648082144119237428816522776534861044712670798123111267113298541167",
"19011679756522918214237064326901138170560812587127533776215776713105468145442",
"1"
],
"B": [
"2646133980078131914507857200375469679789286844739432355665346314081704361405",
"13889943492831913834804319683000878079205443507567487900890258196931968130509",
"1"
],
"C": [
"20734773724461417395552182055150709243833045882953469179956611527056271446574",
"15710414592920317320293397423703814362719064144494256946181196800938530500676",
"1"
],
"Z": [
"20561852897234688380979919287282767037959010378165596947607724154483951499424",
"6122232522674985727127284478945366168578755086215148093727377800176422633844",
"1"
],
"T1": [
"10279993713664578652579403551153368710861572383797672368464388728714854594501",
"1830766094772175078090411988565165501599780889650679924865351804915463619009",
"1"
],
"T2": [
"13453339944260436603772379655045194567668841305436667299518131720401799197975",
"1878530269448865558885111361698648918780579563213553034619643588870422013925",
"1"
],
"T3": [
"7968522597035204585552688871740125090430156719632864203269035766618172641619",
"19811461066576534307499218737564249038349645264023711514858145683802009720956",
"1"
],
"Wxi": [
"15987522046720054484294109486076710847215230863461852476975806408814593489310",
"15454317329417224539157853572276874240734848836935342309579771138054229033523",
"1"
],
"Wxiw": [
"951930434873131110350320837324908721786699471414385262506203998832780237941",
"17429286652635776304236385674029337426996094203091753535498904364644818323108",
"1"
],
"eval_a": "15004998984254783864940761541262947912840270622227584000019303298477580325070",
"eval_b": "1947081577872201452693962008974639354754250794733650209506327813702580206940",
"eval_c": "21521658401977056321791152224833831920988055092058296503354379010082682876287",
"eval_s1": "21173748067731374811694638079145976040116673746120251365684325858495049672557",
"eval_s2": "17743678266096230707311925318440497524696014329588703355930383513494505328606",
"eval_zw": "10543756018853707613533778080554550059272691861721761775521367027104610102236",
"protocol": "plonk",
"curve": "bn128"
}json
[
"1"
]:::
python
# type: ignore
import os
from dotenv import load_dotenv
load_dotenv()
from web3 import Web3
from eth_account import Account
RPC_URL = os.getenv("RPC_URL")
# 使用 HTTPProvider 创建 Web3 实例
w3 = Web3(Web3.HTTPProvider(RPC_URL))
# 导入账户
account = Account.from_key(os.getenv("PRIVATE_KEY"))
w3.eth.default_account = account.address
# 合约地址
contract_addr = "0xbEA8E0F363b1B8469f7971ED157Ec262232D293e"
# 导入abi
with open("abi.json", "r") as f:
import json
abi = json.load(f)
# 创建合约实例
contract = w3.eth.contract(address=contract_addr, abi=abi)
# 导入proof中的24个uint256
with open("proof_plonk.json", "r") as f:
proof_data = json.load(f)
# 导入public_signals
with open("public_plonk.json", "r") as f:
public_signals = json.load(f)
proof = [
int(proof_data["A"][0]),
int(proof_data["A"][1]),
int(proof_data["B"][0]),
int(proof_data["B"][1]),
int(proof_data["C"][0]),
int(proof_data["C"][1]),
int(proof_data["Z"][0]),
int(proof_data["Z"][1]),
int(proof_data["T1"][0]),
int(proof_data["T1"][1]),
int(proof_data["T2"][0]),
int(proof_data["T2"][1]),
int(proof_data["T3"][0]),
int(proof_data["T3"][1]),
int(proof_data["Wxi"][0]),
int(proof_data["Wxi"][1]),
int(proof_data["Wxiw"][0]),
int(proof_data["Wxiw"][1]),
int(proof_data["eval_a"]),
int(proof_data["eval_b"]),
int(proof_data["eval_c"]),
int(proof_data["eval_s1"]),
int(proof_data["eval_s2"]),
int(proof_data["eval_zw"])
]
public = [int(x) for x in public_signals]
# 调用合约方法创建交易
tx = contract.functions.verifyProof(proof, public).build_transaction({
'from': w3.eth.default_account,
'nonce': w3.eth.get_transaction_count(w3.eth.default_account),
'gas': 500000,
'gasPrice': w3.to_wei('20', 'gwei')
})
# 签名
signed = account.sign_transaction(tx)
# 发送交易
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
print("tx hash:", tx_hash.hex())
# 等待状态确认
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print("Transaction receipt:", receipt)
# 对于一个不涉及交易的函数返回值也可以直接call来验证(不会产生交易记录和gas fee)
result = contract.functions.verifyProof(proof, public).call()
print("Result", result)