How are the ethers sent to smart contract in the IBM example - ethereum

I was reading the IBM Example about smartSponsor, and there is this following code:
personal.unlockAccount(thesponsor,"password");
ss.pledge("Good luck with the run!", {from: thesponsor, value: 10000000, gas: 3000000});
While the function pledge is:
function pledge(bytes32 _message) {
if (msg.value == 0 || complete || refunded) throw;
pledges[numPledges] = Pledge(msg.value, msg.sender, _message);
numPledges++;
}
struct Pledge {
uint amount;
address eth_address;
bytes32 message;
}
I was looking for "send" or "transfer" functions. But I could not find any. Therefore I was confused how were the ethers sent from the sponsor to the smart contract?
Update:
How did the sender send the ethers? I was expecting something like .transfer(uint256 amount) or .send(uint256 amount). But it seems that there is no such function call?

They are in magical variable msg. The function pledge uses this variable in the following line:
pledges[numPledges] = Pledge(msg.value, msg.sender, _message);

Related

How can we send ether to payable function in solidity?

I `ve got this function at my .sol file
function enter() public payable{
require(msg.value > .01 ether);
players.push(msg.sender);
}
But when i`m trying to send some eth on it from deployed file it says 'invalid address or ENS name'.
const lotteryContract = new ethers.Contract(
addr,
LotteryArtifact.abi,
acc2
)
const tx ={
from:acc2,
value:ethers.utils.parseEther('2'),
}
await lotteryContract.enter(tx)
Seems like it`s syntactically error in this way of calling it.Also i tried to send it this way
const tx ={
to:lotteryContract.enter(),
value:ethers.utils.parseEther('2'),
}
await acc1.sendTransaction(tx)
Testing this 'enter' function in remix ide logging this
enter image description here
According to the screenshot can anyone explain does 0xf8e81D47203A594245E36C48e151709F0C19fBe8 means the 'enter' function address?

How to add ETH as parameter when calling solidity contract function on web3

I have created smart contract with function:
function putOrder() external payable {
require(msg.value == itemPrice);
(bool sent, bytes memory data) = shopManager.call{value: msg.value}("");
require(sent, "Failed to purchase");
}
This just checks if eth/bnb value is properly passed to the function and then sends it to manager address.
This is how my function on web3 with react looks like:
const putOrder() = async () => {
...
window.contract.methods.orderStuff().send({from: accounts[0]}).on(
'receipt', function(){
processOrder();
}
);
...
}
Obviously I get an error that itemPrice is not met. So how do I pass eth/bnb value to send trough web3 to contract function call?
You can pass it to the send() function argument as a property named value. Its value is the amount of wei (not the amount of ETH) to be sent.
It's just an override of the transaction params (the transaction that executes the contract function). So you could also use it to override gas value, nonce and other params if you need.
.send({
from: accounts[0],
value: 1 // 1 wei
})
.send({
from: accounts[0],
value: web3.utils.toWei(1, 'ether') // 1 ETH == 10^18 wei
})

Estimating gas of an ERC20 transfer

I'd like to estimate the gas of a simple ERC20 transfer between two addresses. The web3.js docs on estimateGas are admittedly confusing:
// using the callback
myContract.methods.myMethod(123).estimateGas({gas: 5000000}, function(error, gasAmount){
if(gasAmount == 5000000)
console.log('Method ran out of gas');
});
The myMethod(123) is what I find confusing. What is that for? The following is what I'm currently thinking, but I'm getting TypeError: contract.methods.send is not a function. What should I substitute for myMethod(123)?
try {
await contract.methods
.send("0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe")
.estimateGas({ gas: 60000 }, (error, gasAmount) => {
return gasAmount;
});
} catch (err) {
console.log(err);
}
send() refers to a contract method called send. You do not have send in your Solidity Contract source code.
Instead, try contract.methods.myMethod.send
A bit late, but you need to look for the function in the smartcontract you want to call and replace myMethod(123) for the function in the contract you are calling.
For example, if you are working with the pancakeswap contract and check in the code the function function deposit(uint256 _pid, uint256 _amount) public {...} (line 1674), you will need to do this:
const estimatedGas = await contract.methods.deposit(123, 0).estimateGas({from: "0x345})
You need to pass the args to deposit in order to make it work.

Restricting a sender from withdrawing more than available balance

I am working on a simple bank smart contract example but I am having trouble getting the contract to restrict a sender from withdrawing more than the remaining balance. Here is my function within the contract:
function withdraw(uint withdrawAmount) public returns (uint) {
assert(balances[msg.sender] >= withdrawAmount);
balances[owner] -= withdrawAmount;
emit LogWithdrawal(msg.sender, withdrawAmount, balances[msg.sender]);
return balances[msg.sender];
}
Here is the .js test:
it("should not be able to withdraw more than has been deposited", async() => {
await instance.enroll({from: alice})
await instance.deposit({from: alice, value: deposit})
await catchRevert(instance.withdraw(deposit + 1, {from: alice}))
})
I was thinking maybe assert(.....) but that didn't work so any assistance would be appreciated.
First of all, you should use require instead of assert in this case. That being said your code seems ok, so make sure you are keeping track of the user balances correctly.
Your code is not consistent, you check the balance for msg.sender, but withdraw from owner.
It should be the correct version:
function withdraw(uint withdrawAmount) public returns (uint) {
require(balances[msg.sender] >= withdrawAmount);
balances[msg.sender] -= withdrawAmount;
emit LogWithdrawal(msg.sender, withdrawAmount, balances[msg.sender]);
return balances[msg.sender];
}

Why the function of address.transfer() only can send 1ether in my contract?

Why the function of address.transfer() only can send 1ether in my contract? It will report errors when the value greater than 1 ether or less than 1 ether.
My code:
pragma solidity ^0.4.24;
contract Lottery{
uint public winn;
//抽奖者
struct lottery{
uint money; //奖金
address name; //名字(地址)
}
//庄家地址
address private bankerAddress = 0x8b3234612c7D3b805F4c9CF1Aa55Cc47B82A0769;
//得奖者数量
uint32 public count;
//得奖者集合
lottery public l;
//初始化
constructor()public {
count=0;
}
event getRandom (
uint indexed _win);
//开始抽奖的函数,返回奖金
function start() public payable{
//随机数生成
uint win= uint(keccak256(now, msg.sender, now)) % 100;
win = win % 12 +1;
winn = win;
l.money = winn;
l.name = msg.sender;
//发奖金操作
msg.sender.transfer(winn*10000000000000000);
//监听事件
getRandom(winn);
}
function () public payable{}
}
Below is javascript code:
lotteryInstance.start.sendTransaction({
from: '0x8b3234612c7D3b805F4c9CF1Aa55Cc47B82A0769',
value: 10000000000000000,
gas: 210000,
gasPrice: web3.toWei('1000', 'gwei')
});
And the error messages:
MetaMask - RPC Error: Error: Error: [ethjs-rpc] rpc error with payload {"id":7309825988666,"jsonrpc":"2.0","params":["0xf8721f85e8d4a510008303345094bcd5d351e5850774d1f720328dac1c8732d68eb7872386f26fc1000084be9a6555822d45a0a07b903c493ba6dee96a54bc74344d1c668cd3d9e8a7c757fdc5daa664ff4271a01bb6799a02054ecf1c8c5be51d6748b2c086eb330091b2e0500d43e756666f69"],"method":"eth_sendRawTransaction"} Error: VM Exception while processing transaction: revert
Uncaught (in promise) Error: Error: Error: [ethjs-rpc] rpc error with payload {"id":7309825988666,"jsonrpc":"2.0","params":["0xf8721f85e8d4a510008303345094bcd5d351e5850774d1f720328dac1c8732d68eb7872386f26fc1000084be9a6555822d45a0a07b903c493ba6dee96a54bc74344d1c668cd3d9e8a7c757fdc5daa664ff4271a01bb6799a02054ecf1c8c5be51d6748b2c086eb330091b2e0500d43e756666f69"],"method":"eth_sendRawTransaction"} Error: VM Exception while processing transaction: revert
In your JS code below:
lotteryInstance.start.sendTransaction({
from: '0x8b3234612c7D3b805F4c9CF1Aa55Cc47B82A0769',
value: 10000000000000000, // Here is the amount of ETH you give to start fuction
gas: 210000,
gasPrice: web3.toWei('1000', 'gwei')
});
The tx is failing maybe because you're giving (ETH) an amount that you may not have! Do you have value: 10000000000000000 many Ethers?
If no, then pass some amount you have, as you haven't given any conditions about the amount in your contract, you can give the smallest possible amount.
PS: The ETH your contract is receiving is not stored anywhere, it may lead to loss of Ethers.