微博地址:Sina Visitor System
在Mainnet发布时,æternity将提供两种智能合约语言:Sophia和Varna。我们将在另一篇文章中讨论Varna。今天我们专注于Sophia。
索菲亚智能合约语言
索菲亚是两种智能合约语言中更具表现力的。在接下来的几段中,我们将介绍一些使其成为卓越的智能合约语言的功能。我们编写了一个教程,解释并说明了其中一些功能作为代码示例。
功能编程
索菲亚是ML家族的一种功能语言。我们选择了函数式编程范例,因为它可以更容易地编写正确的程序 - 这对于智能合约尤其重要。功能语言的质量使它们(可能)比使用命令式范例编写的程序更可靠包括受限制的可变状态,更少的副作用,更易于阅读的代码组件,更好的并发处理以及易于调试和测试。
状态
Sophia没有任意可变状态,但只有与每个合同实例关联的有限形式的状态。可以在此处找到状态特定代码和访问状态的方法的示例。
强类型
Sophia是一种强类型语言,这意味着编译器会检查分配给变量的值是否确实是在编译时为此变量声明的类型。能够指定并自动证明智能合约的属性使Sophia成为更安全的智能合约语言。
第一类对象
在Sophia中,以下组件是第一类对象:智能合约,oracles,名称和状态通道。这意味着它们可以直接使用,而不是由代码库定义,使这些对象更容易访问,更便宜,同时降低代码的复杂性。
模式匹配
Sophia具有基于ReasonML的模式匹配,允许简化的控制流程和构建易于阅读的控制语句的能力。
众筹例子
为了说明上面提到的一些功能,我们写了一个简单的Crowdfunding Campaign智能合约示例,我们想要分享:
/*
-
A simple crowd funding example.
-
Not production code (do not use)!
*/
contract FundMe =
type state = { contributions : map(address, uint),
total : uint,
beneficiary : address,
deadline : uint,
goal : uint }
private function require(b : bool, err : string) =
if(!b) abort(err)
public function init(beneficiary, deadline, goal) : state =
{ contributions = Map.empty,
beneficiary = beneficiary,
deadline = deadline,
total = 0,
goal = goal }
// — API —
// Contribute to the project
public stateful function contribute() =
require(chain.height < state.deadline, “Deadline has passed”)
let amount =
switch(Map.lookup(call.caller, state.contributions))
None => call.amount
Some(n) => n + call.amount
put(state{ contributions[call.caller] = amount,
total = state.total + call.amount })
// Withdraw funds after the deadline.
public stateful function withdraw() =
require(chain.height >= deadline, “Cannot withdraw before deadline”)
if(call.caller == state.beneficiary)
withdraw_beneficiary()
elif(is_contributor(call.caller))
withdraw_contributor()
else
abort(“Not a contributor or beneficiary”)
// — Private functions —
private function is_contributor(addr) =
Map.member(addr, state.contributions)
private stateful function withdraw_beneficiary() =
require(state.total >= state.goal, “Project was not funded”)
transaction(SpendTx({recipient = state.beneficiary,
amount = state.total }))
put(state{ beneficiary = #0 })
private stateful function withdraw_contributor() =
require(state.total < state.goal, “Project was funded”)
let to = call.caller
transaction(SpendTx({recipient = to,
amount = state.contributions[to]}))
put(state{ contributions[to] = 0 })
不远的将来
除了我们正在进行的æpps进展外,我们还在开发一些新的开发工具,我们将在不久的将来宣布这些工具。请继续关注更多信息,并随时直接在论坛或GitHub中与我们联系。