Solidity
使用 dapptools 編寫測試時,如何將交易作為特定錢包地址發送?
我在玩 dapptools:dapp
我想編寫一個測試來檢查 OpenZeppelin 的 ERC721
transferFrom(..)
函式實現的氣體。這是我的測試:
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.6; import "ds-test/test.sol"; import "./DemoErc721.sol"; contract DemoErc721Test is DSTest { DemoErc721 a; address testWallet = address(0x7E67aF7FF72cb87b7B0100cA8128F4673D185234); address testWallet2 = address(0x7E67af7FF72Cb87B7b0100ca8128f4673D185235); function setUp() public { a = new DemoErc721(); } function mintMultiple(uint256 numToMint) public { a.mint(testWallet, numToMint); assertEq(a.balanceOf(testWallet), numToMint); } function testMint_1() public { mintMultiple(1); } function testMint_2() public { mintMultiple(2); } function testMint_3() public { mintMultiple(3); } function testMint_4() public { mintMultiple(4); } function testMint_5() public { mintMultiple(5); } function testTransfer() public { mintMultiple(1); a.transferFrom(testWallet, testWallet2, 1); } }
您可以在
mintMultiple
函式中看到,我們總是在向testWallet
地址鑄造代幣。所以在最後的測試中
testTransfer()
,我希望能夠從testWallet
另一個錢包轉移,因為testWallet
是 NFT 的所有者,擁有 tokenId1
。但是,我認為我編寫此測試的方式導致呼叫地址成為此測試合約的地址,而不是
testWallet
地址。Hardhat 中的類似邏輯是這樣的:
最後,要從另一個帳戶執行合約的方法,您需要做的就是將合約與正在執行的方法連接起來:
await greeter.connect(addr1).setGreeting("Hallo, Erde!");
所以我的問題是,如何模擬
transferFrom
從 進行函式呼叫testWallet
?
你不能 - 可以創建一個測試使用者合約或使用 Foundry,它有一個 .prank() 作弊碼
您可以創建另一個名為
TokenUser
. 在建構子中使用令牌實例對其進行初始化。現在,定義使用者可以對令牌進行的呼叫並圍繞它編寫一個包裝函式。像這樣的東西contract TokenUser{ Token token; constructor(Token token_) public { token = token_; } function doTransfer(address to, uint amount) public returns (bool){ return token.transfer(to, amount); } ... //other functions }
現在在
setUp()
測試合約中,創建一個令牌實例並將地址傳遞給使用者。contract TokenTest is DSTest{ Token token; TokenUser user1; TokenUser user2; function setUp() public { token = new Token("[required_inputs]"); user1 = new TokenUser(token); user2 = new TokenUser(token); } // rest of the contract }
對於測試功能,您可以使用使用者實例
function testSomething() public { user1.transfer(address(user2),100); user2.approve(address(user1),100); }
該方法可用於模擬從不同賬戶(賬戶為不同的TokenUser合約)發送交易。dapphub 有一個優雅的實現範例,你可以在這裡找到它。