如何从客户端向Rust智能合约函数传递Option<T>类型参数?
向Rust智能合约的Option参数传递值的方案
Rust的Option<u128>本质是可选值类型,分为Some(u128)(携带具体数值)和None(无值)两种情况。不同客户端的传递方式取决于你的智能合约所属生态(EVM兼容链/Substrate系链),以下是具体实现:
一、JavaScript/TypeScript 客户端
1. EVM兼容合约(如Solang编写的Rust合约)
EVM生态中,Option<u128>对应Solidity的uint128?类型,主流库(ethers.js、web3.js)会自动处理编码:
- 传递
Some(u128):直接传入BigInt类型的数值(或普通整数,若数值在安全范围内)// ethers.js 示例 const contract = new ethers.Contract(contractAddress, abi, signer); await contract.yourFunction(BigInt("12345678901234567890")); // 对应Some(12345678901234567890) - 传递
None:直接传入null或undefinedawait contract.yourFunction(null); // 对应None
2. Substrate系合约(如ink!编写的合约)
Substrate使用SCALE编码,需通过polkadot.js等库传递对应结构:
- 传递
Some(u128):传入包含Some字段的对象,值为BigInt// polkadot.js API 示例 await api.tx.contracts.call( contractAddress, 0, // gas限制 0, // 附带转账金额 api.createType('Option<u128>', { Some: BigInt("12345") }) ).signAndSend(signer); - 传递
None:传入包含None字段的空对象await api.tx.contracts.call( contractAddress, 0, 0, api.createType('Option<u128>', { None: {} }) ).signAndSend(signer);
二、Python 客户端
1. EVM兼容合约
使用web3.py时,直接传递整数或None即可:
from web3 import Web3 w3 = Web3(Web3.HTTPProvider("rpc_url")) contract = w3.eth.contract(address=contract_address, abi=abi) # 传递Some(u128) tx_hash = contract.functions.yourFunction(12345678901234567890).transact({"from": account}) # 传递None tx_hash = contract.functions.yourFunction(None).transact({"from": account})
2. Substrate系合约
使用substrate-interface库时,需传入对应字典结构:
from substrateinterface import SubstrateInterface, Contract substrate = SubstrateInterface(url="ws://localhost:9944") contract = Contract.create_from_address(contract_address=contract_address, substrate=substrate) # 传递Some(u128) call = contract.compose_call( call_function="your_function", call_params={"your_option_param": {"Some": 12345}} ) # 传递None call = contract.compose_call( call_function="your_function", call_params={"your_option_param": {"None": None}} ) # 发送交易 substrate.create_signed_extrinsic(call=call, keypair=keypair).submit()
三、Curl 工具直接调用RPC
1. EVM兼容链
需先对参数进行ABI编码,可通过cast(Foundry工具)生成编码后的data:
# 生成Some(123)的编码数据 cast abi-encode "yourFunction(uint128?)" 123 # 输出示例:0x...(编码后的十六进制字符串) # 生成None的编码数据 cast abi-encode "yourFunction(uint128?)" null
再用curl发送RPC请求:
curl -X POST https://your-evm-rpc-url \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "eth_sendTransaction", "params": [ { "to": "0xYourContractAddress", "data": "0x编码后的字符串", "from": "0xYourAccount", "gas": "0x5208", "gasPrice": "0x3b9aca00" } ], "id": 1 }'
2. Substrate系链
需对参数进行SCALE编码:
None的SCALE编码为0x00Some(123)的SCALE编码为0x01+ u128的小端十六进制编码(123对应0x7b000000000000000000000000000000),即0x017b000000000000000000000000000000
然后用curl发送RPC请求:
curl -X POST https://your-substrate-rpc-url \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "author_submitExtrinsic", "params": [ "0x编码后的交易数据(包含合约调用和参数SCALE编码)" ], "id": 1 }'
内容的提问来源于stack exchange,提问作者duman
相关产品推荐
相关产品推荐

