我的代码:
const owners = [{
address: "0x1Ebda288BB081747680e356bc6f1A0b29B39Ae3d",
privateKey: ""
}]
let sender = owners[0].address
let senderPrivateKey = owners[0].privateKey
let SAFE_ADDRESS = "0x7B7DADc784d3ddB36F3fBF0900e9C933A1fFa0Cc"
let CHAIN_ID = 137
//SAFE TRANSACTION DATA
let tx = {
to: '0x7B7DADc784d3ddB36F3fBF0900e9C933A1fFa0Cc', //contract to call
value: 0, //native token value in wei
data: '0x0', //data to call contract with
operation: 0, // 0 = CALL, 1 = DELEGATECALL, 2 = CREATE
safeTxGas: 0, //gas limit for calls to other contracts
baseGas: 0, //gas used for safeTx (signature checks...) excluding calls to other contracts
gasPrice: 0, // gas price used for the refund calculation
gasToken: "0x0000000000000000000000000000000000000000", //native token (ETH/BNB...)
refundReceiver: "0x0000000000000000000000000000000000000000", //address to receive gas refunds, if 0x0, tx.origin (original caller) will be used
signatures: "0x"
}
let nonce = await safeWeb3Instance.methods.nonce().call() //can be also stored off-chain, if there are multiple pending txs not yet executed
let msg = await safeWeb3Instance.methods.encodeTransactionData(tx.to, tx.value, tx.data, tx.operation, tx.safeTxGas, tx.baseGas, tx.gasPrice, tx.gasToken, tx.refundReceiver, nonce).call()
//SIGN SAFE TRANSACTION
for (i in owners){
let signature = await web3.eth.accounts.sign(msg, owners[i].privateKey)
signature.signature = signature.signature.replace(signature.v.substring(2), (parseInt(signature.v.substring(2), 16) + 4).toString(16)) //add 4 to v
tx.signatures += signature.signature.substring(2); //substring to remove 0x
}
let params = Object.values(tx)
let data = safeEthersInterface.encodeFunctionData("execTransaction", params)
//ON-CHAIN TRANSACTION
let rawTransaction = {
"from": sender,
"nonce": "0x" + nonce.toString(16),
"gasPrice": web3.utils.toHex(gasPrice * 1e9),
"gasLimit": web3.utils.toHex(gasLimit),
"to": SAFE_ADDRESS,
"data": data,
"chainId": CHAIN_ID
};
let createTransaction = await web3.eth.accounts.signTransaction(rawTransaction, senderPrivateKey)
let receipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction);由于GS026错误(提供了无效的所有者)它失败了,但是用于签名数据的地址是有效的所有者。(例如https://polygonscan.com/tx/0x7a9e9edc5ba5b625de45a50b94c8d21d8d57ad57c6180eb0881503eb0f315597)
我做错了什么?
发布于 2022-04-12 10:20:32
目前,您使用encodeTransactionData获取要与web3.eth.accounts.sign签名的消息。正确的方法是getTransactionHash。
对于合同,在签署交易数据之前必须对其进行散列。sign方法首先在其哈希之前追加Ethereum消息前缀(请参阅https://web3js.readthedocs.io/en/v1.2.11/web3-eth-accounts.html#sign),因此您将得到一个错误的结果。
请记住,如果您使用多个所有者,他们的签名需要按照他们的地址进行排序(更多信息在这里:https://docs.gnosis-safe.io/contracts/signatures)
https://ethereum.stackexchange.com/questions/125904
复制相似问题