In this tutorial I will explain how to add a feature to your Solidity smart contract to control or lock token transfers. This feature will allow you to turn transfers on and off to prevent snipe bots, attacks, or implement other use cases in a smart contract.
We will review two different methods to lock & unlock token transfers that can be implemented in your contract before deployment. The time lock method based on block number or the flag method based on a boolean. There are more ways to accomplish this however we will discuss these two methods to introduce you to the concept. Each implementation has its positives and negatives so you will need to decide what works best for your situation.
Solidity token lock based on block number
Adding a modifier to the transfer function in your Solidity smart contract will allow you to prevent transfers. The modifier can check the current block number and if it is not greater then the block number specified in the contract the transfer will not occur. This will result in a time delay and transfers will not occur until the block number is greater then the block number specified in the contract.
In the example below the current block number must be higher than 6 million or the function does not run. You can approximate a time in the future because Ethereum blocks are created at an average rate of 15 seconds.
//function modifier checks the block number
modifier checkBlock() {
require(block.number > 6000000, 'Can Not Trade');
_;
}
//add this modifier to the transfer function
function transfer(address _to, uint _value) public checkBlock returns (bool success) {
if (_value > 0 && _value <= balanceOf(msg.sender)) {
__balanceOf[msg.sender] -= _value;
__balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
return false;
}
Solidity token lock based on true or false flag
The owner of a contract can set a boolean flag that defines if the tokens are tradable or not. In the Solidity smart contract add a state variable, a setter and a function modifier. Add the modifier to the beginning of the transfer function to block trades if the state is false.
The example below has a few more features. Read the comments in the code below to understand all the components needed for this implementation.
// add the two state variables to your contract
// specify the owner
// added a true false flag that will be used to indicate if the tokens are tradable
address owner;
bool public transferable = false;
// add two function modifiers
// a modifier to check the owner of the contract
// a modifier to determine if the transferable flag is true of false
modifier onlyOwner() {
require(msg.sender == owner, 'Not Owner');
_;
}
modifier istransferable() {
require(transferable==false, 'Can Not Trade');
_;
}
// Add a setter to change the transferable flag
// only the owner of the contract can call because a modifier is specified
function isTransferable(bool _choice) public onlyOwner{
transferable = _choice;
// add the function modifier to the transfer function
// if the transferable==false then one can not trade
function transfer(address _to, uint _value) public istransferable returns (bool success) {
if (_value > 0 && _value <= balanceOf(msg.sender)) {
__balanceOf[msg.sender] -= _value;
__balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
return false;
}
Try it in Remix
Above are two different implementations to prevent token transfers in a Solidity smart contract. This feature is useful for many different use cases. Some examples are:
- Distribute an allowance to multiple people
- A game that transfers items
- Ownership in something that must be held for a period of time
- The list goes on
This code is for learning and entertainment purposes only. The code has not been audited and use at your own risk. Remember smart contracts are experimental and could contain bugs.
Click here for more information about how to use the Ethereum test network and how to obtain test ETH.