Solidity

如何使用 Web3.js v1.2.1 創建用於將乙太坊從 multiSig 合約發送到帳戶的交易數據

  • April 4, 2020

我正在使用標準的 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

類似問題但已過時:

如何使用 web3js 傳輸 ERC20 代幣

如何使用 Web3 API 發送 ERC20 令牌?

發送乙太幣非常簡單:

// 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

引用自:https://ethereum.stackexchange.com/questions/80697