一、说明
EVM网络泛指遵循ERC20协议标准的evm公链及侧链网络,包括但不限于BSC,HECO,Base,arbitrum,ETH等公链或者layer2网络。在evm网络上铭文原理是通过在在交易过程中附加calldata数据,将数据永久保存到链上,避免了只有metadata元数据上链,但是真实数据需要存储在ipfs上的问题。eth上的NFT只在链上保存元数据metadata,真实的图片保存到ipfs网络上,会存在真实nft图片被恶意篡改的风险。evm上的铭文是对所有交易hash进行索引,在交易的calldata中获取铭文数据。相比layer2更加的去中心话,gas费用更低,数据安全性更好。因此铭文目前以及作为layer2的一种可替代方案。
本案例代码主要实现在dapp前端页面直接部署铭文和批量铸造铭文,以及针对指定的钱包地址授权。只有获取授权资格的钱包地址才能使用该dapp工具部署铭文和批量铸造mint铭文。
以下为在线部署铭文和批量铸造mint铭文的dapp前端展示效果:
主要功能包括:
- 支持直接在dapp前端在线部署铭文
- 支持直接在dapp前端页面批量铸造mint铭文
- 支持显示当前链接的钱包地址,当前链接的链名称,钱包地址余额
- 用户在线购买钱包地址授权,只有经过授权的钱包地址才能在线部署和批量铸造mint铭文
二、dapp完整版代码实现如下:
- 前端dapp页面布局代码:
<div class="tab">
<button class="tablinks" onclick="openTab(event, 'batchMint')">铭文批量铸造Mint</button>
<button class="tablinks" onclick="openTab(event, 'deploy')">铭文部署Deploy</button>
<button class="tablinks" onclick="openTab(event, 'approve')">购买授权</button>
</div>
<div id="deploy" class="tabcontent deploy-params">
<h3>铭文部署Deploy</h3>
<form>
<label for="delploy-input">铭文(十六进制):</label>
<input type="text" id="delploy-input">
<p class="form-note">例如: data:,{"p":"bsc-20","op":"deploy","tick":"BNBS","max":"2100000000000000","lim":"1000"}</p>
<p class="form-note">其中: p协议类型,op操作类型,tick代币名称,max发行总量,lim单次mint数量</p>
</form>
<div id="deploy-response" class="deploy-info">
<p id="deploy-status"></p>
<p id="deploy-owner"></p>
<p id="deploy-timestamp"></p>
<p id="deploy-hash"></p>
</div>
<div class="button-group">
<button class="connect-wallet-btn" onclick="connWalletDeploy()">连接钱包</button>
<button class="execute-contract-btn" onclick="deploy()">部署Deploy铭文</button>
</div>
<table class="wallet-property">
<tr>
<td>钱包地址:</td>
<td id="wallet-address">0x0000000000000000000000000000000000000000</td>
</tr>
<tr>
<td>钱包余额:</td>
<td id="wallet-balance">0.000000</td>
</tr>
<tr>
<td>链ID:</td>
<td id="wallet-chainid">1</td>
</tr>
<tr>
<td>链名:</td>
<td id="wallet-chainname">Ethereum Mainnet</td>
</tr>
</table>
</div>
2. 链端哑合约主要实现铭文部署和批量铸造mint铭文核心功能代码
pragma(:rubidity, "1.0.0")
contract(:ERC20, abstract: true) {
event(:Transfer, { from: :address, to: :address, amount: :uint256 })
event(:Approval, { owner: :address, spender: :address, amount: :uint256 })
string(:public, :name)
string(:public, :symbol)
uint8(:public, :decimals)
uint256(:public, :totalSupply)
mapping(({ address: :uint256 }), :public, :balanceOf)
mapping(({ address: mapping(address: :uint256) }), :public, :allowance)
constructor(name: :string, symbol: :string, decimals: :uint8) {
s.name=name
s.symbol=symbol
s.decimals=decimals
}
function(:approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {
s.allowance[msg.sender][spender] = amount
emit(:Approval, owner: msg.sender, spender: spender, amount: amount)
return true
}
function(:transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {
require(s.balanceOf[msg.sender] >= amount, "Insufficient balance")
s.balanceOf[msg.sender] -= amount
s.balanceOf[to] += amount
emit(:Transfer, from: msg.sender, to: to, amount: amount)
return true
}
function(:transferFrom, { from: :address, to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {
allowed = s.allowance[from][msg.sender]
require(s.balanceOf[from] >= amount, "Insufficient balance")
require(allowed >= amount, "Insufficient allowance")
s.allowance[from][msg.sender] = allowed - amount
s.balanceOf[from] -= amount
s.balanceOf[to] += amount
emit(:Transfer, from: from, to: to, amount: amount)
return true
}
function(:_mint, { to: :address, amount: :uint256 }, :internal, :virtual) {
s.totalSupply += amount
s.balanceOf[to] += amount
emit(:Transfer, from: address(0), to: to, amount: amount)
}
function(:_burn, { from: :address, amount: :uint256 }, :internal, :virtual) {
require(s.balanceOf[from] >= amount, "Insufficient balance")
s.balanceOf[from] -= amount
s.totalSupply -= amount
emit(:Transfer, from: from, to: address(0), amount: amount)
}
}
contract(:Upgradeable, abstract: true) {
address(:public, :upgradeAdmin)
event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })
event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })
constructor(upgradeAdmin: :address) {
s.upgradeAdmin=upgradeAdmin
}
function(:setUpgradeAdmin, { newUpgradeAdmin: :address }, :public) {
require(msg.sender == s.upgradeAdmin, "NOT_AUTHORIZED")
s.upgradeAdmin=newUpgradeAdmin
emit(:UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin)
}
function(:upgradeAndCall, { newHash: :bytes32, newSource: :string, migrationCalldata: :string }, :public) {
upgrade(newHash: newHash, newSource: newSource)
(success, data) = address(this).call(migrationCalldata)
require(success, "Migration failed")
}
function(:upgrade, { newHash: :bytes32, newSource: :string }, :public) {
currentHash = this.currentInitCodeHash
require(msg.sender == s.upgradeAdmin, "NOT_AUTHORIZED")
this.upgradeImplementation(newHash, newSource)
emit(:ContractUpgraded, oldHash: currentHash, newHash: newHash)
}
}
contract(:EtherBridge, is: [:ERC20, :Upgradeable], upgradeable: true) {
event(:BridgedIn, { to: :address, amount: :uint256 })
event(:InitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32 })
event(:WithdrawalComplete, { to: :address, amount: :uint256, withdrawalId: :bytes32 })
address(:public, :trustedSmartContract)
mapping(({ bytes32: :uint256 }), :public, :withdrawalIdAmount)
mapping(({ address: :bytes32 }), :public, :userWithdrawalId)
constructor(name: :string, symbol: :string, trustedSmartContract: :address) {
require(trustedSmartContract != address(0), "Invalid smart contract")
self.ERC20.constructor(name: name, symbol: symbol, decimals: 18)
self.Upgradeable.constructor(upgradeAdmin: msg.sender)
s.trustedSmartContract=trustedSmartContract
}
function(:bridgeIn, { to: :address, amount: :uint256 }, :public) {
require(msg.sender == s.trustedSmartContract, "Only the trusted smart contract can bridge in tokens")
_mint(to: to, amount: amount)
emit(:BridgedIn, to: to, amount: amount)
}
function(:bridgeOut, { amount: :uint256 }, :public) {
withdrawalId = tx.current_transaction_hash
require(s.userWithdrawalId[msg.sender] == bytes32(0), "Withdrawal pending")
require(s.withdrawalIdAmount[withdrawalId] == 0, "Already bridged out")
require(amount > 0, "Invalid amount")
s.userWithdrawalId[msg.sender] = withdrawalId
s.withdrawalIdAmount[withdrawalId] = amount
_burn(from: msg.sender, amount: amount)
emit(:InitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: withdrawalId)
}
function(:markWithdrawalComplete, { to: :address, withdrawalId: :bytes32 }, :public) {
require(msg.sender == s.trustedSmartContract, "Only the trusted smart contract can mark withdrawals as complete")
require(s.userWithdrawalId[to] == withdrawalId, "Withdrawal id not found")
amount = s.withdrawalIdAmount[withdrawalId]
s.withdrawalIdAmount[withdrawalId] = 0
s.userWithdrawalId[to] = bytes32(0)
emit(:WithdrawalComplete, to: to, amount: amount, withdrawalId: withdrawalId)
}
}
3. 该dapp扩展支持铭文swap功能,可以在线实时交易任意数量的铭文代币,不用整张交易的swap资金池哑合约代码如下:
pragma(:rubidity, "1.0.0")
contract(:ERC20, abstract: true) {
event(:Transfer, { from: :address, to: :address, amount: :uint256 })
event(:Approval, { owner: :address, spender: :address, amount: :uint256 })
string(:public, :name)
string(:public, :symbol)
uint8(:public, :decimals)
uint256(:public, :totalSupply)
mapping(({ address: :uint256 }), :public, :balanceOf)
mapping(({ address: mapping(address: :uint256) }), :public, :allowance)
constructor(name: :string, symbol: :string, decimals: :uint8) {
s.name=name
s.symbol=symbol
s.decimals=decimals
}
function(:approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {
s.allowance[msg.sender][spender] = amount
emit(:Approval, owner: msg.sender, spender: spender, amount: amount)
return true
}
function(:transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {
require(s.balanceOf[msg.sender] >= amount, "Insufficient balance")
s.balanceOf[msg.sender] -= amount
s.balanceOf[to] += amount
emit(:Transfer, from: msg.sender, to: to, amount: amount)
return true
}
function(:transferFrom, { from: :address, to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {
allowed = s.allowance[from][msg.sender]
require(s.balanceOf[from] >= amount, "Insufficient balance")
require(allowed >= amount, "Insufficient allowance")
s.allowance[from][msg.sender] = allowed - amount
s.balanceOf[from] -= amount
s.balanceOf[to] += amount
emit(:Transfer, from: from, to: to, amount: amount)
return true
}
function(:_mint, { to: :address, amount: :uint256 }, :internal, :virtual) {
s.totalSupply += amount
s.balanceOf[to] += amount
emit(:Transfer, from: address(0), to: to, amount: amount)
}
function(:_burn, { from: :address, amount: :uint256 }, :internal, :virtual) {
require(s.balanceOf[from] >= amount, "Insufficient balance")
s.balanceOf[from] -= amount
s.totalSupply -= amount
emit(:Transfer, from: from, to: address(0), amount: amount)
}
}
contract(:FacetSwapV1Callee, abstract: true) {
function(:facetSwapV1Call, { sender: :address, amount0: :uint256, amount1: :uint256, data: :bytes }, :virtual, :external)
}
contract(:FacetSwapV1ERC20, is: :ERC20, abstract: true) {
constructor {
self.ERC20.constructor(name: "FacetSwap V1 ERC20", symbol: "FACET-V1", decimals: 18)
}
}
contract(:IFacetSwapV1Factory02, abstract: true) {
function(:feeTo, :external, :view, returns: :address)
function(:lpFeeBPS, :external, :view, returns: :uint256)
}
contract(:Upgradeable, abstract: true) {
address(:public, :upgradeAdmin)
event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })
event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })
constructor(upgradeAdmin: :address) {
s.upgradeAdmin=upgradeAdmin
}
4. 实现流动性liquidity添加和删除以及代币兑换swap功能核心代码如下:
function(:swap, { amount0Out: :uint256, amount1Out: :uint256, to: :address, data: :bytes }, :external) {
require(s.unlocked == 1, "FacetSwapV1: LOCKED")
s.unlocked=0
require(amount0Out > 0 || amount1Out > 0, "FacetSwapV1: INSUFFICIENT_OUTPUT_AMOUNT")
(_reserve0, _reserve1, _) = getReserves
require(amount0Out < _reserve0 && amount1Out < _reserve1, "FacetSwapV1: INSUFFICIENT_LIQUIDITY")
balance0 = 0
balance1 = 0
_token0 = s.token0
_token1 = s.token1
require(to != _token0 && to != _token1, "FacetSwapV1: INVALID_TO")
if amount0Out > 0
_safeTransfer(_token0, to, amount0Out)
end
if amount1Out > 0
_safeTransfer(_token1, to, amount1Out)
end
if data.length > 0
FacetSwapV1Callee(to).facetSwapV1Call(msg.sender, amount0Out, amount1Out, data)
end
balance0 = ERC20(_token0).balanceOf(address(this))
balance1 = ERC20(_token1).balanceOf(address(this))
amount0In = if balance0 > _reserve0.-(amount0Out)
balance0 - (_reserve0 - amount0Out)
else
0
end
amount1In = if balance1 > _reserve1.-(amount1Out)
balance1 - (_reserve1 - amount1Out)
else
0
end
require(amount0In > 0 || amount1In > 0, "FacetSwapV1: INSUFFICIENT_INPUT_AMOUNT")
lpFeeBPS = IFacetSwapV1Factory02(s.factory).lpFeeBPS
balance0Adjusted = balance0 * 1000 - (amount0In * lpFeeBPS).div(10)
balance1Adjusted = balance1 * 1000 - (amount1In * lpFeeBPS).div(10)
require(balance0Adjusted * balance1Adjusted >= uint256(_reserve0).*(_reserve1).*((1000 ** 2)), "FacetSwapV1: K")
_update(balance0, balance1, _reserve0, _reserve1)
s.unlocked=1
emit(:Swap, sender: msg.sender, amount0In: amount0In, amount1In: amount1In, amount0Out: amount0Out, amount1Out: amount1Out, to: to)
}
至此,完成EVM网络上铭文部署deploy和批量铸造mint的dapp完整代码实现所有操作流程。
pdf+视频比特币链ARC20+BRC20+ORC20+SRC20,EVM网络BSC20+ERC20+ARB20+SPL20+POL20铭文deploy部署Mint铸造打新教程下载:
比特币链ARC20+BRC20+ORC20+SRC20,EVM网络BSC20+ERC20+ARB20+SPL20+POL20铭文deploy部署Mint铸造(铭文铭刻deploy部署、铸造mint、转账transfer、upgrade、cancel、挂单unisat、Migration、marketplace、EVM Marketing挂单交易)教程下载:
pdf+视频比特币链ARC20+BRC20+ORC20+SRC20,EVM网络BSC20+ERC20+ARB20+SPL20+POL20铭文deploy部署Mint铸造打新教程下载地址:
添加VX或者telegram获取全程线上免费指导
评论前必须登录!
注册