以太坊智能合约基础(理解智能合约/Solidity)
无需编程经验,也可以帮助你了解Solidity独特的部分;如果本身就有相应的编程经验如java,python等那么学起来也会非常的轻松
一、Solidity和EVM字节码
实际上以太坊链上储存的就是EVM的字节码,编译好的程序;EVM和Solidity实际上就和java中的jvm虚拟机和java语言的关系
Solidity是静态类型的
类似于Java,C,Rust 而非python或者js
例子:-整数:uint(256位无符号整数)
int(256位带符号整数)
for (uint i = 0;i<10;i++){users[i].balance = 1;}
二、数据类型
**值类型(value Type)**布尔值,整数型等等
**引用类型(Reference Type)**包括数组和结构体,这类变量占用的空间大,赋值是直接传递地址值(类似于Java的指针)
**映射类型 (mapping Type) ** 类似于java的map key--value
-映射:健值存储/哈希表
-每个键初始值都映射为0
-没有内置的方法来查询映射的长度,或者、迭代其非零元素。可以使用单独的变量
三、函数签名
智能合约的代码总是包含在函数或者是一个运算程序中的;和Java,python的编程语言的函数类似
构造函数
第一次创建合约时调用
用于自定义设置或给出初始状态
BoardAction的智能合约函数,类似于java中的赋值操作,把constructor的address的地址值赋值给上面的public的值
solidity
contract BoardAction{
address public president;
address public vicePresident;
constructor(address initialPresident,address initialVP) public {
/** initialize the contract **/
president = initialPresident;
vicePresident = initialVP;
}
}
四、可见修饰器
用于函数
solidity
function calledByAnyone()public {/*anyone can all */}
function calledInternally() internal {/* only called by another funcation in this contract*/}
用于实例变量;几乎和java的public和private一摸一样
solidity
int public myPublicField;
int private myPrivateField;
问:myPrivateField所取的值时秘密的吗?
刚开始学习 solidity
时,pure
和 view
关键字可能令人费解,因为其他编程语言中没有类似的关键字。solidity
引入这两个关键字主要是因为 以太坊交易需要支付气费(gas fee)。合约的状态变量存储在链上,gas fee 很贵,如果计算不改变链上状态,就可以不用付 gas
。包含 pure
和 view
关键字的函数是不改写链上状态的,因此用户直接调用它们是不需要付 gas 的(注意,合约中非 pure
/view
函数调用 pure
/view
函数时需要付gas)。
solidity
function ordinary() public {/*can modify state and call other functions*/}
function viewOnly() public view {/*cannot modify any storage or call another ono-view funcation*/}
funcation localOnly() public pure {/*doesnot even read any state either*/}
五、事件
这个类似于java中日志
查看合约状态主要有两种方式:
-使用***++View函数++***,例如用于公共字段的getter函数
-查看***++事件日志++***。是否可以"订阅"合约中的事件
首先使用event声明一个事件,然后在想要查看的地方emit这个事件即可
六、调用其他合约的方法
如下代码所示Token为外部的合约接口;tokenA,tokenB外部合约地址实例;sqap1函数的调用
solidity
abstract contract Token {
function transferFrom (address from,address to,uint amount) public virtual;
}
contract Exchanger {
Token tokenA = Token(address(0x00))
Token tokenB = Token(address(0x00))
function sqap1(address Alice,address Bob) public{
tokenA.transferFrom(Alice,Bob,1);
tokenB.transferFrom(Bob,Alice,1);
}
}
七、使用原生代币
在solidity中接受和使用以太坊币
如下代码。有一个acceptExactlyTwoEther函数可以被以太坊的以太币接受,然后还有函数修饰器payable 一定要指定payable ,如果没有指定payable修饰的话那么以太坊将会拒绝所有的以太币。
solidity
function acceptExactlyTwoEther() public payable returns(uint) {
require(msg.value >= 2.0 ether);
uint refund = msg.value - 2.0 ether;
payable(msg.sender).transfer(refund);
return address(this).balance;
}
读取当前时间
solidity
function plcaeBid(int price) public {
require(block.timestamp <= deadline);
}
关于区块的其他元数据也是可以得到的
总结
本文介绍了Solidity智能合约的基本概念和核心特性。Solidity类似于Java/C等静态语言,编译为EVM字节码运行。主要知识点包括:1)数据类型分为值类型、引用类型和映射类型;2)函数签名与构造函数机制;3)可见性修饰符(public/private)和状态修改标识(view/pure);4)事件机制用于日志记录;5)调用外部合约的方法;6)原生代币处理需使用payable修饰符;7)可读取区块时间等元数据。文章通过类比Java等传统语言,帮助开发者快速理解Solidity独特的设计逻辑,为智能合约开发打下基础。