Solidity
如何使用 Web3.js v1.2.1 創建用於將乙太坊從 multiSig 合約發送到帳戶的交易數據
我正在使用標準的 MultiSigWallet 合約。我的目標是使用/ ( )中使用的 web3創建*數據參數。*交易應該將 Ether 從 MultiSigWallet 發送到特定的使用者地址。
executeTransaction``external_call``bytes memory data
堅固性
contract MultiSigWallet { struct Transaction { address destination; uint256 value; bytes data; bool executed; } /// @dev Allows an owner to submit and confirm a transaction. /// @param destination Transaction target address. /// @param value Transaction ether value. /// @param data Transaction data payload. /// @return transactionId transactionId Returns transaction ID. function submitTransaction(address destination, uint256 value, bytes memory data) public returns (uint256 transactionId) { transactionId = addTransaction(destination, value, data); confirmTransaction(transactionId); } /// @dev Allows an owner to confirm a transaction. /// @param transactionId Transaction ID. function confirmTransaction(uint256 transactionId) public ownerExists(msg.sender) transactionExists(transactionId) notConfirmed(transactionId, msg.sender) { confirmations[transactionId][msg.sender] = true; emit Confirmation(msg.sender, transactionId); executeTransaction(transactionId); } /// @dev Allows anyone to execute a confirmed transaction. /// @param transactionId Transaction ID. function executeTransaction(uint256 transactionId) public ownerExists(msg.sender) confirmed(transactionId, msg.sender) notExecuted(transactionId) { if (isConfirmed(transactionId)) { Transaction storage txn = transactions[transactionId]; txn.executed = true; if ( external_call( txn.destination, txn.value, txn.data.length, txn.data ) ) { emit Execution(transactionId); } else { emit ExecutionFailure(transactionId); txn.executed = false; } } } // call has been separated into its own function in order to take advantage // of the Solidity's code generator to produce a loop that copies tx.data into memory. function external_call(address destination, uint256 value, uint256 dataLength, bytes memory data) internal returns (bool) { bool result; assembly { let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention) let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that result := call( sub(gas(), 34710), // 34710 is the value that solidity is currently emitting // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) + // callNewAccountGas (25000, in case the destination address does not exist and needs creating) destination, value, d, dataLength, // Size of the input (in bytes) - this is what fixes the padding problem x, 0 // Output is ignored, therefore the output size is zero ) } return result; }
} }
Web3
multisigInstance = MultiSigWallet.new(owners, confirmations); dataParameter = multisigInstance.contract.transfer.getData(depositAddress, amount);
此程式碼導致錯誤
TypeError: Cannot read property 'getData' of undefined
multisigInstance = MultiSigWallet.new(owners, confirmations); dataParameter = multisigInstance.contract.methods.transfer(toAddress, amount).encodeABI();
此程式碼導致錯誤導致
TypeError: multisigInstance.contract.methods.transfer is not a function
類似問題但已過時:
發送乙太幣非常簡單:
// Submit transfer operation const receipt = await multisig.submitTransaction(recipient, amount, "").send(); // Obtain transactId from receipt const transactionId = ...; // When confirmed by owners majority it will execute
發送 ERC20 稍微複雜一些
// Encode ERC20 transfer operation const data = token.methods.transfer(recipient, amount).encodeABI(); // Submit operation to multisig await multisig.submitTransaction(token.options.address, 0, data).send(); // Rest is the same as a regular transfer