Posted By : Niraj
A smart contract is a PC program or an exchange convention that consequently executes, controls, or reports important occasions and activities as per the particulars of an agreement or an understanding legtimately.
The thought of smart contracts was first proposed by Nick Szabo in 1994. Szabo is a legitimate researcher and cryptographer known for laying the preparation for computerized money. In those days, there was little intrigue or action in brilliant agreements because that there was no computerized stage for making contracts.
Blockchain is perfect for putting away keen agreements given its innovation, security, and unchangeble nature. A keen agreement information is encoded on a common record, making it difficult to lose the data put away in the blocks.
Developers can store practically any sort of information on blockchain, and they have a wide assortment of exchange alternatives to browse during savvy contract sending.
The code we will break down now makes an essential type of digital money. Any individual who has an Ethereum keypair can trade these coins. Be that as it may, just the agreement maker can give new ones.
Now, we will create smart contracts for allowance wallet.
It is a very basic smart contract. It can receive Ether and it’s possible to withdraw Ether, but all in all, not very
useful quite yet. Let’s see if we can improve this a bit in the next step.
pragma solidity ^0.6.1;
contract SharedWallet {
function withdrawMoney(address payable _to, uint _amount) public {
_to.transfer(_amount);
}
//prior sol0.6 the receive function is the funciton() external payable
receive() external payable {
}
}
Also, Read | Solidity Smart Contract Vulnerabilities and Ways To Mitigate Them
In this step, we restrict withdrawal to the owner of the wallet. How can we determine the owner? It’s the user who
deployed the smart contract.
pragma solidity ^0.6.1;
contract SharedWallet {
address owner;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "You are not allowed");
_;
}
function withdrawMoney(address payable _to, uint _amount) public onlyOwner {
_to.transfer(_amount);
}
receive() external payable {
}
}
Having the owner-logic directly in one smart contract isn’t very easy to audit. Let’s break it down into smaller parts
and re-use existing audited smart contracts from OpenZeppelin for that. The latest OpenZeppelin contract does not
have an owner () function anymore, so we have to create our own. Note that the owner () is a function from the
Ownable.sol contract.
pragma solidity ^0.6.1;
import " https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol ";
contract SharedWallet is Ownable {
function isOwner() internal view returns(bool) {
return owner() == msg.sender;
}
function withdrawMoney(address payable _to, uint _amount) public onlyOwner {
_to.transfer(_amount);
}
receive() external payable {
}
}
Also, read | Publishing a Smart Contract on Geth Console
In this step, we are adding a mapping so we can store the address => uint amounts. This will be like an array that stores
[0x123546...] an address, to a specific number. So, we always know how much someone can be withdrawn. We also add
a new modifier that checks: Is it the owner itself or just someone with allowance?
pragma solidity ^0.6.1;
import " https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol ";
contract SharedWallet is Ownable {
function isOwner() internal view returns(bool) {
return owner() == msg.sender;
}
mapping(address => uint) public allowance;
function addAllowance(address _who, uint _amount) public onlyOwner {
allowance[_who] = _amount;
}
modifier ownerOrAllowed(uint _amount) {
require(isOwner() || allowance[msg.sender] >= _amount, "You are not allowed!");
_;
}
function withdrawMoney(address payable _to, uint _amount) public ownerOrAllowed(_amoun
t) {
require(_amount <= address(this).balance, "Contract doesn't own enough money");
_to.transfer(_amount);
}
receive() external payable {
}
}
Without reducing the allowance on withdrawal, someone can continuously withdraw the same amount over and
over again. We have to reduce the allowance for everyone other than the owner.
function reduceAllowance(address _who, uint _amount) internal ownerOrAllowed(_amount) {
allowance[_who] -= _amount;
}
function withdrawMoney(address payable _to, uint _amount) public ownerOrAllowed(_amoun
t) {
require(_amount <= address(this).balance, "Contract doesn't own enough money");
if(!isOwner()) {
reduceAllowance(msg.sender, _amount);
}
_to.transfer(_amount);
}
pragma solidity ^0.6.1;
import " https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol ";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/math/SafeMath.sol";
contract Allowance is Ownable {
using SafeMath for uint;
event AllowanceChanged(address indexed _forWho, address indexed _byWhom, uint _oldAmount
, uint _newAmount);
mapping(address => uint) public allowance;
function isOwner() internal view returns(bool) {
return owner() == msg.sender;
}
function setAllowance(address _who, uint _amount) public onlyOwner {
emit AllowanceChanged(_who, msg.sender, allowance[_who], _amount);
allowance[_who] = _amount;
}
modifier ownerOrAllowed(uint _amount) {
require(isOwner() || allowance[msg.sender] >= _amount, "You are not allowed!");
_;
}
function reduceAllowance(address _who, uint _amount) internal ownerOrAllowed(_amount) {
emit AllowanceChanged(_who, msg.sender, allowance[_who], allowance[_who].sub(_amount
));
allowance[_who] = allowance[_who].sub(_amount);
}
function renounceOwnership() public onlyOwner {
revert("can't renounceOwnership here"); //not possible with this smart contract
}
}
November 21, 2024 at 11:39 am
Your comment is awaiting moderation.