一门面向合约的高级编程语言,主要用来编写以太坊只能合约。
Solidity受C语言,Python和js影响,但为编译成为以太坊虚拟机字节码在EVM上执行,很多特性和限制都和EVM相关。
Solidity 是静态类型语言,支持继承、库、自定义复杂类型和其他特性。目前Solidity 编程的最好方式是用 Remix。Remix是一个基于 Web 浏览器的 IDE,它可以让你编写Solidity智能合约,然后部署并运行该智能合约。
Solidity语法接近js,一种面向对象的语言作为一种真正意义上运行在网络上的去中心合约,它又有很多不同:
最外层是contract关键字,Solidity是一门面向合约的语言。
contract就是一种很好地体现,所有的合约结构都是在contract包围之中。像Java这种OO语言,最外层是 class 包围,但在 Solidity 中不是定义一个类,而是定义一个合约。
合约中可包含状态变量、函数、事件、自定义类型等。
contract SolidityContract {}
合约的最简结构,首先是contract关键字,后面是合约名字,花括号“”中是合约体。
pragma solidity ^0.4.22;
contract SolidityContract {
uint8 public id;
string internal name;
struct Funder {
address addr;
uint amount;
}
Funder fund = Funder(msg.sender, 1);
bytes bytesValue = "a";
bytes1 bytes1Value = 0x1;
uint8[3] nums = [1, 2, 3];
// dynamicNums 定义有误,因为声明了大小为1的数组,却试图初始化3个元素
// uint8[1] dynamicNums = [1, 2, 3]; // 这行代码是错误的
uint8[] dynamicNums = [1, 2, 3]; // 修正为数组动态大小
mapping (address => uint) myMapping;
enum Color { Red, Green }
address ownedAddr;
function myFunction() internal returns (bool res) {
throw; // 在Solidity 0.4.22中,应该使用 revert() 或 require() 来处理错误
}
modifier checkTime(uint _time) {
require(now >= _time);
_;
}
event LogEvent(address victim); // 修正了 "aderess" 为 "address"
}
在Solidity文件中第一行:
pragma solidity ^0.4.22;
pragma,编译指示的意思,不是program,是为说明这个Solidity文件可以使用哪些版本的编译器编译。
上面编译指示的意思就是编译器版本version的范围是0.4.23<=version<0.5.0
也可直接指定:
pragma solidity >=0.4.24 <0.5.0
网页版的Solidity编辑器。Remix非常强大,可直接在浏览器中使用,不用开发者自己搭建开发环境。
Remix项目现在已经迁移到remix-ide:https : /github.com/etheraml/renix-ide 找到项目。
无需本地搭建,可直接使用的服务
solidity/https ://ethereum.github.io/browser
git clone https://github.com/ethereum/remix-ide.git
cd remix-ide
npm install
npm run setupremix
npm start
一般使用打包好的NPM模块即可,先执行安装remix-ide:
npm install remix-ide -g
启动remix-ide: remix-ide
然后在浏览器中访问http://localhost:8080就可以看到完整的Remi页面。
主要有文件管理、控制台、代码编辑、编译、运行和配置等相关模块。
类似其他语言的成员变量,因为Solidity是一门面向合约的语言,以太坊的交易本质其实是一种状态机,从一
种状态到另一种状态。
合约的本质也是在合适的条件触发交易。
pragma solidity >=0.4.22 <0.6.0;
constant StateVar {
string name;
uint32 id;
}
也叫本地变量。局部变量不仅是函数中的变量,参数也属局部变量,包括入、出参都是局部变量。
状态变量和局部变量:
pragma solidity >=0.4.22 <0.6.0;
contract Variable {
// 状态变量
uint8 stateVar;
function variableTest(uint8 inArgLocalVar) returns (uint8 outArgLocalVar){
uint8 functionBodyLocalVar;
return 0;
}
}
简化版函数定义模型:
function function Name (<parameter types>)[returns (<return types>)]
若函数有返回值,须用returns关键字 + 函数参数的返回值类型列表。
Solidity允许返回多值,所以要确定返回顺序。
相近关键字:
支持返回多值。
Solidity 函数的返回值不是一个单独类型,而是一个类型列表。
返回值的声明放在最后。
pragma solidity >=0.4.22 <0.6.0;
/**
返回多值
*/
contract ReturnContract {
// 只有一个返回值uint8
function singleReturnTest() public pure returns (uint8) {
uint8 num = 111;
return num;
}
// 返回多值
function multipleReturnTestOne()
public
pure
returns (uint8, uint16, string)
{
uint8 num = 111;
return (num, num, "multiple");
}
}
Solidity也有构造函数,就是和合约同名的函数,但只允许有一个。
合约创建时调用相关的代码完成初始化工作。
pragma solidity ^0.4.24;
contract StateVariableContract {
string name;
uint32 id;
// 使用constructor关键字标识构造函数
constructor() {
id = 10;
}
function getId() returns(uint32){
return id;
}
}
创建完合约执行 getld 就可发现ID已变为10。
constructor也可有参数,除非是为了继承,因此一般不要有参数。
constructor只能是public或internal类的,默认public。
如被标注为intemnal,合约就会被标注为abstract 的抽象合约。
执行合约时经常会出现一些异常,都是EVM底层抛出的,Solidity也支持使用throw抛出异常,不同的是Solidity不支持异常捕获,抛出异常之后会回滚所有之前执行的操作。
在Remix中编译创建合约执行throwTest方法,可发现执行前、后num值都是10,并没有被修改。
throw关键字已不再推荐,因使用throw的场景一般是条件不满足的情况。可先执行相关条件检查,使用require、assert、rever函数代替throw。
pragma solidity >=0.4.22 <0.6.0;
contract ThrowContract {
uint8 public num = 10;
function throwTest() public {
num = 100;
//抛出异常,自动回滚
throw;
}
}
支持两种注释:
注释一般都是为了说明合约、接口、库函数相关功能和注意事项。可直接当文档使用。
所以Solidity编译器很贴心地准备了从注释生成文档的功能。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。