Truffle

如何使用 sendTransaction 呼叫回退方法?

  • January 20, 2022

我正在測試委託呼叫漏洞。我已經創建了兩個契約來做到這一點。

錢包庫.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyWalletLibrary {
   uint private value = 0;

   function setValue(uint a) public {
       value = a;
   }

   function getValue() public view returns (uint) {
       return value;
   }
}

和 MyWallet.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyWallet {
   uint private value = 0;
   address private walletLibrary;

   constructor(address a) {
       walletLibrary = a;
   }

   fallback () external payable {
       (bool success, ) = walletLibrary.delegatecall(msg.data);
       if (! success) revert();
   }
}

現在我想通過 MyWallet 中的回退函式呼叫 MyWalletLibrary.setValue。所以我創建了一個松露單元測試文件:

let MyWallet = artifacts.require("MyWallet")

it('delegate-test', async () => {
   let accounts = await web3.eth.getAccounts()
   let MyWalletDeployed = await MyWallet.deployed()

   web3.eth.sendTransaction({
       from: accounts[0],
       to:   MyWalletDeployed.address,
       data: '123'
   });
})

根據文件我應該使用 sendTransaction(),但是這個 sendTransaction() 沒有指定呼叫的方法,也就是“setValue”。

我該怎麼做?

您的數據應該是函式簽名和傳遞給它的參數。

這就是你在 Solidity 中的做法:walletLibrary.delegatecall(abi.encodePacked("setValue(uint256)", "123"))

對於 web3,您將需要使用此文件

const myData = web3.eth.abi.encodeFunctionCall({
   name: 'setValue',
   type: 'function',
   inputs: [{
       type: 'uint256',
       name: 'a'
   }]
}, ['123']);

web3.eth.sendTransaction({
       from: accounts[0],
       to:   MyWalletDeployed.address,
       data: myData
   });

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