Truffle 测试具有发送价值

Truffle test in solidity with sending value

正在从 SA 复制我的 question

我有一个带有 public 函数的简单合约,它可以接收值并根据该值做一些事情:

pragma solidity >= 0.8.0 < 0.9.0;

contract ContractA {


    uint public boughtItems = 0;
    uint price = 10;
    address []  buyers; 

    function buySomething() public payable {
        require(msg.value >= price, "Sent value is lower"); 
        boughtItems++;
        buyers.push(msg.sender);
    }
}

在我的 Truffle 项目的测试文件夹中,我有测试合同:

pragma solidity >=0.8.0 <0.9.0;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/TicketsRoutes.sol";

contract TestTicketsRoutes {

    ContractA instance;
    

    address account1 = 0xD8Ce37FA3A1A61623705dac5dCb708Bb5eb9a125;

    function beforeAll() public {
        instance = new ContractA();
    }

    function testBuying() public {
        //Here I need to invoke buySomething with specific value from specific address
        instance.buySomething();

        Assert.equal(instance.boughtItems, 1, "Routes amount is not equal");
    }
}

如何在我的 TestContractA 中使用传递值和发送者调用 ContractA 的函数?

您可以使用低级 call() Solidity 函数来传递值。

(bool success, bytes memory returnedData) = address(instance).call{value: 1 ether}(
    abi.encode(instance.buySomething.selector)
);

但是,为了从不同的发件人执行 buySomething() 函数,您需要从与 TestTicketsRoutes 部署地址不同的地址发送它。

所以你需要改变你的方法并从链下脚本(而不是链上测试合约)执行测试,它允许你从不同的发送者签署交易。由于您标记了问题 truffle,这里有一个使用 Truffle JS 套件 (docs) 执行合约函数的示例。

const instance = await MyContract.at(contractAddress);
const tx = await instance.buySomething({
    from: senderAddress,
    value: web3.toWei(1, "ether")
});