How to use transfer function in solidity - blockchain

I created smart contract to transfer ETH from one account to another, ETH deduction occurs but send to other address(which is not specified). Please help me to resolve this problem.
//SPDX-License-Identifier:MIT
pragma solidity ^0.8.12;
contract ETH{
address public buyer;
uint public amt;
address public seller;
constructor(){
seller = msg.sender;
}
function add(address payable _buyer) payable public{
buyer = _buyer;
payable(buyer).transfer(amt);
}
function bal() view public returns(uint){
return buyer.balance;
}
function s() payable public returns(uint){
return msg.value;
}
}

The default value of amt is 0 and your code does not set this property (to a non-zero value) anywhere.
Which effectively makes your .transfer(amt) function to send 0 ETH to the buyer and keep all the ETH, that you sent along with the transaction, in the contract.
If you want to redirect the sent amount, there's the msg.value global variable, which reflects the current value sent with the transaction.
payable(buyer).transfer(msg.value);

Related

TypeError: Member "push" not found or not visible after argument-dependent lookup in address[] storage ref

could anyone help me with this??
used online remix in order to create a calucator using following criteria
Add Log of transactions using the event/emit
Each time one of the methods is called you will add
the address (msg.sender)
the action (“add”, “subtract”…)
the number
ii. Create a modifier “isOwner” like we did in class and add it to all the
methods in the calculator.
iii. Add a check using require or revert for the divide method to make sure
you are not dividing by zero (0).
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
contract Calculator{
mapping(address => uint256) public transactions;
address public owner;
address[] public transList; //// Showing to modify this line of code
constructor() {
owner = msg.sender;
}
modifier isOwner() {
require(msg.sender == owner, "Sender is not Owner");
_;
}
function whoIsOwner() public isOwner view returns (address) {
return owner;
}
uint256 public total =0;
uint256 public current_total =0;
function add(uint256 _amount) isOwner public{
total = total + _amount;
transList.push(msg.sender);
transList.push("add"); /// Error in this line
transList.push(_amount);
}

Does it make sense to manage balance manually inside smartcontract?

I am using Solidity to deploy smartcontract to a test Ethereum network launched by Ganache. I read some demo code of contract and one of them looks like:
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.4;
pragma experimental ABIEncoderV2;
contract Ledger {
struct TransferRequest {
string title;
uint256 amount;
string bsb;
string accountName;
string accountNumber;
}
mapping(address => uint256) balances;
address payable owner;
event Transfered(bool _success, address _from, address _to, uint256 amount);
constructor() payable {
owner = payable(msg.sender);
balances[tx.origin] = 10000;
}
function sendCoin(address payable receiver, uint256 amount)
payable public
{
require(msg.sender == owner);
if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Transfered(true, msg.sender, receiver, amount);
}
function getBalance(address addr) public view returns (uint256) {
return balances[addr];
}
}
As you can see above that the contract manages the balance by itself rather than using the balance from the blockchain. There is no real ether transfer inside sendCoin method. Does this mean there is no real transaction in the blockchain. Then what the point of building a contract like that. What would be the relationship between balance managed by blockchain and balance managed by contract?
the contract manages the balance by itself rather than using the balance from the blockchain
Each state change (in this case change of balances storage property value) is recorded on the blockchain. So the contract is reading the balance from the blockchain.
However, the way Ethereum network is designed, an address can only have few properties - its bytecode (non-zero bytecode means it's a smart contract), its balance, and few others. Since there's only one property for balance (and not a list of balances), it's used for the native ETH balance. Any token balances are stored in the contracts of the respective tokens.
You can read more about the token balance storage design in the final version of ERC-20 and the linked documents. This is the first standard that introduced tokens on Ethereum.

Allowance and transfer tokens from contract B using contract A to user address X

I have deployed contract A.
Now I am creating gateway contract B and I want to send some tokens of contract A to user address X using owner address.
Worth to mention that contract A owner is the same as contract B.
I do the following
contract A is Ownable { // this one already deployed by owner
constructor() {
owner = msg.sender; // owner address is 0x123
approve(msg.sender, totalSupply); // let's approve all tokens for owner
}
function transferFrom(address from, address to, uint256 value) public returns (bool) {
require(value <= allowed[from][msg.sender], "Not allowed!");
// let's skip other logic
}
}
contract B is Ownable { // gateway contract will be deployed and executed by same owner
A contractA = ETC20(0x111);
address payable X = 0x333;
constructor() {
owner = msg.sender; // owner address is 0x123
}
function giveAwayTokens(uint256 value) {
contractA.transferFrom(owner, X, value);
}
}
When I execute "giveAwayTokens" function from owner address (0x123), I get error "Not allowed!".
So I am a bit confused right now, because the allowance of owner from owner is max supply.
Or maybe the msg.sender is contractB itself?
Please enlighten me what I am doing wrong here, thank you
When ContractB calls ContractA, the msg.sender in ContractA is ContractB address.
Based on the code and the error message, the owner (0x123) didn't allow ContractB to spend their tokens.
You need to set the value of allowed[<owner>][<ContractB>] to be at least the amount of tokens that you want to send.
Most likely you have an approve() function (defined in the token standard) that you can use. In the linked example, the caller of the function would be the owner, the spender would be the ContractB and the value would be any value equal or higher than the amount of tokens that you want to send (mind the decimals).

Refund all addresses entered on solidity contract

I have a problem related to refund the users entered inside the solidity contract. I don't, have any idea if is possible iterate all the players of my contract and refund all of them with all the balance.I read in some tutorials, iterate inside the solidity contract cost a lot of gas depends of the numer of iterations.
contract Lottery{
address payable public manager;
string public name; // short name (up to 32 bytes)
address [] players;
uint256 nTickets;
address winner;
bool enable;
uint256 minimunContribution;
mapping(address => uint) public balances;
constructor (string memory LotteryName, uint minimun, address payable creator) public {
manager = creator;
name = LotteryName;
winner = address(0);
enable = true;
minimunContribution = minimun;
}
modifier restricted() {
require(msg.sender == manager, "Access forbidden");
_;
}
function enterInToLottery() public payable {
require(msg.value > minimunContribution && enable == true, "Insufficient funds to allow transfer");
players.push(msg.sender);
balances[msg.sender] += msg.value;
nTickets++;
}
//this function refund
function paybackEther(bool newfinished) public restricted {
enable = !newfinished;
selfdestruct(msg.sender);
}}
Thanks in advance to all.
Yes that can be problematic as it will use a lot of gas and may even hit limits. To solve this it is better to allow the users to withdraw the balance themselves, so they pay for the gas. Or in fact you can allow anybody to make that call. So you can offer a call refund(account:uint256) which transfers the balance (if any) to given account. Note that this would not be using msg.sender, so that anybody (including the admin) can do this transfer.
Keep in mind they need to know that they have a balance, so make sure you're emitting an event or similar. Also provide a balanceOf(address) call so they can check.
Hope this makes sense & works for you.

Where would a transaction take place in my Smart Contract

I am making a simple smart contract that is essentially a ledger that people can sign with a string (UI to come) and then pass onto a next person (using their ether address). I just wanted to create something that could be passed from person to person while recording its journey.
The logic of 'transferring' the signing-ledger is all done within the smart contract, with it existing as a mapping and the key value of an address changing from 0 to 1 signifying ownership (1 person owning it at a time). Because there's no actual transfer of ether/actual monetary value, where would actual ethereum transactions be occurring in this contract?
Also to sign the ledger I verify that the public key signing it has 1 as its value in the mapping, but how would I check that that person owns that public key (using a private key)?
my solidity code so far:
pragma solidity ^0.4.4;
contract Pass{
mapping(address => bool) ownership;
mapping(address => string) notes;
constructor(address genesis) public {
ownership[genesis] = true; //this address starts with it
}
function checkOwnership(address p) public view returns(bool){
if(ownership[p]){
return true;
}
return false;
}
function sign(string signedNote) public returns(uint){ // 1 on success 0 on fail
if(checkOwnership(msg.sender)){ //if msg.sender owns the note
notes[msg.sender] = signedNote;
return 1;
}
return 0;
}
function pass(address recipient) public returns(uint){ // 1 on success 0 on fail
if(checkOwnership(msg.sender)){ //if msg.sender owns the note
ownership[msg.sender] = 0;
ownership[recipient] = 1;
return 1;
}
return 0;
}
function viewNotes(address participant) public returns(string){ // signed note on success nothing on fail
if(notes[participant] !== 0){
return (notes(participant));
}
}
}
The logic of 'transferring' the signing-ledger is all done within the smart contract, with it existing as a mapping and the key value of an address changing from 0 to 1 signifying ownership (1 person owning it at a time)
This is a common pattern known as the owner pattern. You can simplify this by simply keeping track of a single owner address and updating that, instead of using a mapping, since you only care about the current owner. Something as simple as:
address public owner;
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
constructor() {
owner = msg.sender;
}
function transferOwnership(address _owner) onlyOwner {
owner = _owner;
}
Open Zeppelin has a more complete implementation of ownership here.
Because there's no actual transfer of ether/actual monetary value, where would actual ethereum transactions be occurring in this contract?
Transactions do not require ether movement. You can call any public/external function on your contract with a 0 value transaction, and pass data to it. The transaction will execute on the blockchain like any other, and run the code you invoke within the contract.
Also to sign the ledger I verify that the public key signing it has 1 as its value in the mapping, but how would I check that that person owns that public key (using a private key)?
You are already checking is msg.sender matches the whitelisted address. For basic transactions, this means that the transaction has been signed by the address in msg.sender (msg.sender can also be a contract, if another contract calls yours. To check who actually signed the transaction in all scenarios, you must use tx.origin).