I have below smart contract and a test program to test transfer ETH out of contract address, but contract’s ETH balance not changed. I tested withdrawAmount(uint256 amount) but the assertion error occurred. I also use msg.sender.transfer(getBalance()); this work will transfer all balance out of contract, but I want to transfer with my amount with withdrawAmount(uint256 amount) function. How does msg.sender.transfer(amount) work in solidity0.6.10? How can I transfer the ETH’s amount from contract’s address?
$ truffle version Truffle v5.1.26 (core: 5.1.26) Solidity - 0.6.10 (solc-js) Node v10.20.0 Web3.js v1.2.1
#ContractBalanceTest.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.21 <0.7.0;
contract ContractBalanceTest {
address public owner;
constructor() public payable {
owner = msg.sender;
}
modifier onlyOwner () {
require(msg.sender == owner, "This can only be called by the contract owner!");
_;
}
function deposit() payable public {
}
function depositAmount(uint256 amount) payable public {
require(msg.value == amount);
}
function withdraw() payable onlyOwner public {
msg.sender.transfer(address(this).balance);
}
function withdrawAmount(uint256 amount) onlyOwner payable public {
require(msg.value == amount);
require(amount <= getBalance());
msg.sender.transfer(amount); //this not work
//msg.sender.transfer(getBalance()); // this ok
}
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}
#test code
var ContractBalance = artifacts.require('ContractBalanceTest');
contract('test contract balance with eth', function (accounts) {
//console.log(accounts);
let contract, balance;
before(async function () {
contract = await ContractBalance.new({from: accounts[0]});
balance = await contract.getBalance();
console.log('ContractBalanceTest ', contract.address, balance.toString());
console.log('');
});
describe('#deposit', function () {
it('test deposit', async function () {
let one_eth = web3.utils.toWei("1", "ether");
let tx = await contract.depositAmount(one_eth, { from: accounts[1], value : one_eth});
//console.log(tx);
let b = await contract.getBalance();
console.log('ContractBalanceTest ', contract.address, b.toString());
assert.equal( b.toString(), "1000000000000000000", "the contract's balance should be 1 ether");
});
});
describe('#withdraw', function () {
it('test withdraw', async function () {
let half_eth = web3.utils.toWei("0.5", "ether");
let tx = await contract.withdrawAmount(half_eth, { from: accounts[3], value : half_eth});
//let tx = await contract.withdraw({ from: accounts[0], value : half_eth});
//console.log(tx.logs);
let b = await contract.getBalance();
console.log('ContractBalanceTest ', contract.address, b.toString());
assert.equal( b.toString(), "500000000000000000", "the contract's balance should be 0.5 ether" );
});
});
});
#test result
Contract: test contract balance with eth
ContractBalanceTest 0xb7Ff5FB586177E7F489B956e7b218CdeB731B319 0
#deposit
ContractBalanceTest 0xb7Ff5FB586177E7F489B956e7b218CdeB731B319 1000000000000000000
✓ test deposit (131ms)
#withdraw
ContractBalanceTest 0xb7Ff5FB586177E7F489B956e7b218CdeB731B319 1000000000000000000
1) test withdraw
Events emitted during test:
---------------------------
ContractBalanceTest.Transfer(
amount: <indexed> 500000000000000000 (type: uint256)
)
---------------------------
1 passing (508ms)
1 failing
1) Contract: test contract balance with eth
#withdraw
test withdraw:
the contract's balance should be 0.5 ether
+ expected - actual
-1000000000000000000
+500000000000000000
at Context.<anonymous> (test/test_contract_balance.js:34:14)
at process._tickCallback (internal/process/next_tick.js:68:7)
Best Answer
remove payable keyword, and remove value from test code