web3-Remix部署智能合约到"荷兰式"拍卖及以太坊gas费机制细讲
一、使用Remix演示智能合约部署
智能合约的代码编写一般都是在Remix上,Remix的好处的话就是可以在浏览器中快速开发和部署合约,无需在本地安装任何程序,十分适合新手。
对应的网址:https://remix.ethereum.org/
在 Remix
中,左侧菜单有三个按钮,分别对应文件(编写代码)、编译(运行代码)和部署(将合约部署到链上)。点击"创建新文件"(Create New File
)按钮,即可创建一个空白的 Solidity
合约。
第一个Solidity程序"hello web3"
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
contract HelloWeb3{
string public _string = "Hello Web3!";
}
我们详细的讲解一下上述代码的结构
1.第一行代码是注释部分,说明代码所使用的软件许可(license),这里使用的是MIT许可。如果不写许可就会出现警告(warning),然是程序还是可以正常运行的。注释以"//"开头
2.第二行声明源文件所使用的Solidity版本,不同的版本语法有差异。0.8.21的意思就是说源文件的版本不允许小于0.8.21或者大于等于0.9.0。以""开头 --- ";"结尾。
3.下面为代码部分。使用"contract"创建合约并声明合约的名称为"HelloWeb3"。第四行为合约内容,声明了一个名称为_string 的 string类型的变量,并赋值为"Hello Web3!"
编译部署代码
在Remix页面编译代码非常方便,写好代码后,ctrl+s保存即可编译代码。编译完成后找到左侧的部署界面点击"Deploy"部署即可。
如下图可以看到部署完成后现实的"hello web3!"
二、智能合约的案例学习-荷兰式拍卖
荷兰式拍卖在 -- 加密猫 中非常流行
加密猫是以太坊上的第一个大型的NFT应用;是一个在以太坊上的猫咪收集游戏吸引了超过百万的资金。这也是只有区块链技术才能造就的游戏。
加密猫的购买方式基于"荷兰式"拍卖
"立刻购买" 价格在初始设定的时为最高价格。随着时间推移,"立刻购买"的价格随着曲线不断降低。
拍卖过程的任何时刻只要有人参与拍卖,满足对应的条件,获拍者就能够声明并购买到加密猫。
荷兰式拍卖代码
solidity
contract DutchAuction {
//Parameters
uint public initialPrice; uint public biddingPeriod; //初始的拍卖价格;设定拍卖时长
uint public offerPriceDecrement; uint public startTime; //价格下降速率字段;开始拍卖时间戳
//KittyToken外部合约,代表的是被出售的NFT加密猫的地址;seller出售方的地址
KittyToken public kitty; address payable public seller;
//winnerAddress获拍方的地址
address payable winnerAddress;
//立刻购买的函数
function buyNow() public payable {
//确定当前拍卖的价格,通过当前的区块时间-拍卖的开始时间
uint timeElapsed = block.timestamp - startTime;
//起始价格-时间*价格下跌的速率;得到当前价格
uint currPrice = initialPrice - (timeElapsed * offerPriceDecrement);
//用户出价(输入值)
uint userBid = msg.value;
//检查竞拍是否是有效的
//竞拍者的地址
require(winnerAddress == address(0)); //Auction hasnot ended early
//竞拍是否在规定的时间内
require(timeElapsed < biddingPeriod); //Auction hasnot ended by time
//竞拍者是否有足够的资金
require(userBid>=currPrice); //Bid is big enough
winnerAddress = payable(msg.sender);
winnerAddress = transfer(userBid - currPrice); //Refund the difference
seller.transfer(currPrice);
//调用加密猫外部合约,将加密猫的所有权转移给获拍者
kitty.transferOwnership(winnerAddress);
}
}
三、以太坊上的gas费
以太坊上的每一笔交易都需要支付交易费(gas)
交易越复杂支付的gas费就越高,gas费的支付在以太坊上都是使用原生代币来支付的,在以太坊上就是ETH
矿工在每个区块都会对Gas使用设定全局上限;意味着在每个区块中大约可以运行多少段智能合约的代码是有限制的。
每一笔操作都会需要支付特定数量的gas
在执行交易的时候会有一个计数器计算gas的消耗;在执行合约的时候必须要有足够的gas费用,如果gas费用不够的话就无法去执行相应的合约
solidity
contract MyRegistry {
mapping(string => address) public registry;
function registerDomain(string memory domain) public {
// can only reserve new unregistered domain names
//执行完代码后会看到有多少gas的剩余
require(registry[domain] == address(0));
//update the owner of this domain
registry[domain] = msg.sender;
}
}
gas上限和退款
- 每一笔交易都会设定一个gas上限,以及购买gas的价格,以ETH计算
- 预留对应数量的以太坊在交易执行之前支付
- 在合约执行之后,没有使用的gas会被退还
EVM中有索引表,每一个操作符都有对应的gas价格
以太坊虚拟机编码了操作符,不是高级语言
公式(FORMULA)意味着这个操作符对应的gas取决于参数
如果gas用完了会怎么样
- 会出现一个Gas用完(out-of-gas)的异常
- 任何对存储变量,转账等的改动都会回到调用这个方式之前
- 仍然需要支付在出现异常之前每一笔操作所需要的Gas
- 和其他异常一样,可以用其他处理函数捕获(类似于java的try catch)
- 只需使用一部分可用的Gas就可以调用方法
总结
本文介绍了使用Remix部署智能合约的方法以及以太坊gas费机制。首先通过"hello web3"案例演示了Remix编写、编译和部署智能合约的基本流程。其次以加密猫的荷兰式拍卖为例,解析了智能合约在实际应用中的实现逻辑。最后详细讲解了以太坊gas费机制,包括gas的计算方式、上限退款规则以及gas耗尽时的异常处理。文章涵盖智能合约开发的关键环节,为初学者提供了实用的技术指南。