智能合约可以将以太币转移到一个地址,但该地址的余额不会更新
Smart Contract could transfer ether to an address, but the balance of that address does not update
我正在尝试让我的智能合约将其所有余额转移到另一个地址。传输线没有抛出任何错误,但之后合约余额没有改变。
我正在使用带有 ganache 的 web3js 来测试这个功能:
我的合同:
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.12;
contract Lottery {
address payable public manager;
address payable[] public players;
constructor() {
manager = payable(msg.sender);
}
function enterLottery() public payable {
require(msg.value >= .01 ether);
players.push(payable(msg.sender));
}
function getPlayers() public view returns (address payable[] memory) {
return players;
}
function random() public view returns (uint256) {
return
uint256(
keccak256(
abi.encodePacked(block.difficulty, block.timestamp, players)
)
);
}
function pickWinner() public { // this transfer contract balance to the account
uint256 index = random() % players.length;
players[index].transfer(address(this).balance);
}
}
我的测试用例:
beforeEach(async () => {
accounts = await web3.eth.getAccounts();
contract = await new web3.eth.Contract(abi)
.deploy({ data: evm.bytecode.object })
.send({ from: accounts[0], gas: "1000000" })
})
describe("Lottery", () => {
it("Contract has an address? ", () => {
assert.ok(contract.options.address)
})
it("Prize pool can receive ether", async () => {
await contract.methods.enterLottery().send({ from: accounts[1], gas: "1000000", value: "10000000000000000" });
const contractBalance = await web3.eth.getBalance(contract.options.address)
const hasContractReceivedEntry = contractBalance === "10000000000000000";
assert.equal(hasContractReceivedEntry, true)
})
it("Winner can receive the prize pool", async () => {
await contract.methods.enterLottery().send({ from: accounts[1], gas: "1000000", value: "10000000000000000" });
await contract.methods.pickWinner().call();
const contractBalance = await web3.eth.getBalance(contract.options.address)
console.log(contractBalance) // the contract balance should be 0 after the pickWinner call, but it is still 10000000000000000 wei the enterLottery function gave
})
})
编辑:确认智能合约可以运行 enterLottery 和 random() 按预期
await contract.methods.pickWinner().call();
在这一行中,您正在调用一个 read-only 调用 ,它不会更新合同状态。您需要使用 .send()
函数 发送交易 - 就像上一行一样。
我正在尝试让我的智能合约将其所有余额转移到另一个地址。传输线没有抛出任何错误,但之后合约余额没有改变。
我正在使用带有 ganache 的 web3js 来测试这个功能:
我的合同:
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.12;
contract Lottery {
address payable public manager;
address payable[] public players;
constructor() {
manager = payable(msg.sender);
}
function enterLottery() public payable {
require(msg.value >= .01 ether);
players.push(payable(msg.sender));
}
function getPlayers() public view returns (address payable[] memory) {
return players;
}
function random() public view returns (uint256) {
return
uint256(
keccak256(
abi.encodePacked(block.difficulty, block.timestamp, players)
)
);
}
function pickWinner() public { // this transfer contract balance to the account
uint256 index = random() % players.length;
players[index].transfer(address(this).balance);
}
}
我的测试用例:
beforeEach(async () => {
accounts = await web3.eth.getAccounts();
contract = await new web3.eth.Contract(abi)
.deploy({ data: evm.bytecode.object })
.send({ from: accounts[0], gas: "1000000" })
})
describe("Lottery", () => {
it("Contract has an address? ", () => {
assert.ok(contract.options.address)
})
it("Prize pool can receive ether", async () => {
await contract.methods.enterLottery().send({ from: accounts[1], gas: "1000000", value: "10000000000000000" });
const contractBalance = await web3.eth.getBalance(contract.options.address)
const hasContractReceivedEntry = contractBalance === "10000000000000000";
assert.equal(hasContractReceivedEntry, true)
})
it("Winner can receive the prize pool", async () => {
await contract.methods.enterLottery().send({ from: accounts[1], gas: "1000000", value: "10000000000000000" });
await contract.methods.pickWinner().call();
const contractBalance = await web3.eth.getBalance(contract.options.address)
console.log(contractBalance) // the contract balance should be 0 after the pickWinner call, but it is still 10000000000000000 wei the enterLottery function gave
})
})
编辑:确认智能合约可以运行 enterLottery 和 random() 按预期
await contract.methods.pickWinner().call();
在这一行中,您正在调用一个 read-only 调用 ,它不会更新合同状态。您需要使用 .send()
函数 发送交易 - 就像上一行一样。