当前位置: 首页 > 知识库问答 >
问题:

智能合约的合适类型是什么?

易淳
2023-03-14

我想知道用类型化语言(如Haskell或Idris)表达智能合约的最佳方式是什么(例如,您可以编译它以在以太坊网络上运行)。我主要关心的是:什么类型可以捕获合同所能做的一切?

一个简单的解决方案是将协定定义为ethio类型的成员。这种类型类似于Haskell的IO,但它不支持系统调用,而是包括区块链调用,即,它将支持从区块链状态读取和写入区块链状态、调用其他契约、获取块数据等。

-- incrementer.contract

main: EthIO
main = do
   x <- SREAD 0x123456789ABCDEF
   SSTORE (x + 1) 0x123456789ABCDEF

这显然足以执行任何合同,但是:

type Contract action state = {
    act  : UserID -> action -> state -> state,
    init : state
}

因此,一个程序看起来像:

incrementer.contract

main : Contract
main = {
    act _ _ state = state + 1,
    init          = 0
}

也就是说,定义初始状态、操作类型以及当用户提交操作时该状态的变化方式。这将允许人们定义任何不涉及发送/接收金钱的任意合同。大多数区块链都有某种货币,大多数有用的合同不知何故涉及金钱,所以这种类型的限制太大了。

我们可以通过将货币逻辑硬编码到上面的类型中来使上面的类型知道货币。因此,我们会得到这样的东西:

type Contract action state = {
    act        : UserID -> action -> state -> state,
    init       : state,
    deposit    : UserID -> Amount -> state -> state,
    withdrawal : UserID -> Amount -> state -> Maybe state
}
type Contract = {
    act  : UserID -> Action -> Map ContractID State -> State,
    init : State
}

现在我在黑暗中。我知道我对这个问题没有正确的抽象,但我不确定它会是什么。看起来问题的根源是我不能正确地捕捉跨合同通信的现象。哪种具体类型更适合定义任意智能契约?

共有1个答案

吕文林
2023-03-14

在回答主要问题之前,我将尝试更精确地定义用Haskell或Idris编写代码并将其编译为在类似以太坊的区块链上运行意味着什么。Idris可能更适合这样做,但我将使用Haskell,因为这是我熟悉的。

总的来说,我可以设想使用Haskell代码为区块链虚拟机生成字节码的两种方式:

>

  • 将EVM字节码构建为Haskell数据的库

    这就是GHC后端变得相关的地方。编译器插件(目前可能必须是GHC分叉,就像GHCJS一样)可以将Haskell编译成EVM字节码。这将对程序员隐藏单个操作码,因为它们确实太强大了,不能直接使用,而是由编译器基于代码级构造发出。您可以认为EVM是一个不纯的、不安全的、有状态的平台,类似于CPU,语言的工作是将其抽象出来。相反,您可以使用常规的Haskell函数样式编写,并且在后端和自定义编写的运行库的限制下,现有的Haskell库可以编译并可用。

    还有混合方法的可能性,其中一些我将在本文末尾讨论。

    在这篇文章的其余部分,我将使用GHC后端方法,我认为这是最有趣和相关的。我确信核心思想将会延续到库方法中,也许经过一些修改。

    >

  • 作为具有一组操作的构建基元数据类型

    -- Not really a declaration but a compiler builtin
    -- data Eth = ...
    

    由于EVM的大部分类似于普通计算机,主要是它的内存模型,所以一种更狡猾的方法是将其别名为io:

    type Eth = IO
    

    在编译器和运行时提供适当支持的情况下,这将允许现有的基于IO的功能,如IOREF不加修改地运行。当然,许多IO功能(如文件系统交互)将不受支持,并且必须提供一个自定义base包而不提供这些功能,以确保使用它们的代码不会编译。

    -- | Information about arbitrary accounts
    balance  :: Address -> Eth Wei
    contract :: Address -> Eth (Maybe [Word8])
    codeHash :: Address -> Eth Hash
    
    -- | Manipulate memory; subsumed by 'IORef' if the 'IO' monad is used
    newEthVar   :: a -> Eth (EthVar a)
    readEthVar  :: EthVar a -> Eth a
    writeEthVar :: EthVar -> a -> Eth ()
    
    -- | Transfer Wei to a regular account
    transfer :: Address -> Wei -> Eth ()
    
    selfDestruct :: Eth ()
    
    gasAvailable :: Eth Gas
    

    其他基本功能,包括函数调用,包括决定调用是常规(内部)函数调用、html" target="_blank">消息调用还是委托消息调用,将由编译器和运行时处理。

    我们现在开始回答最初的问题:智能合约的合适类型是什么?

    type Contract = ???
    

    合同需要:

      null
    newtype Contract in out = Contract (Wei -> Env -> in -> Eth out)
    
    call :: Contract in out -> Wei -> in -> Eth out
    

    当然,这是一种简化;例如,它不咖喱输入类型。据推测,编译器将为每个可见契约生成唯一的操作,类似于solidity。甚至可能不适合使此原语可用。

    另外一个细节:EVM支持构造函数,即在合同创建时执行的EVM代码,以允许使用环境信息。因此,由程序员编写的合同的类型是:

    main :: Eth (Contract in out)
    main = return . Contract $ \wei env a -> do
      ...
    

    我省略了许多细节,比如错误处理、日志记录/事件、坚固性互操作/FFI和部署。尽管如此,我希望我已经给出了针对区块链智能合约环境的函数式语言编程模型的有用概述。

    在写这篇文章时,我大量参考了以下参考资料:

    • 以太坊黄纸,以太坊虚拟机的特性
    • 坚实ABI
    • 坚固性构建

    其他有趣的资源:

  •  类似资料:
    • 指导编写一个EOSIO的智能合约 模块 Account API 查询账户数据的API. Chain API 查询链内部状态的API. Database API 存储和检索EOS.IO区块链的数据API根据以下广泛结构来组织数据. Math API 定义常用的数学函数. Action API 定义用于查询操作属性的API. Memory API 定义常用的记忆功能. Console API 使应用程

    • 编程语言 使用golang作为编程语言(对部分关键字限制,以保证处理的有序性),而不是重新创造编程语言。 golang是一个简单、易用的编程语言,它有完善的帮助文档和开发工具。 它是强类型校验,编译阶段就能够校验发现很多bug。 它是模块化的,本系统能够简单屏蔽外部功能,使智能合约处在简单可预期的环境中。 已经有大量的golang开发人员,他们如果要开发智能合约,非常容易上手。 智能合约的分类 公

    • 介绍 EOSIO 智能合约 编写智能合约需要的必备技能 C / C++ 相关 基于 EOSIO 的块链使用的是 WebAssembly(http://webassembly.org/) (WASM) 来执行用户编写的智能合约。WASM 是一种新兴的 Web 标准,广泛支持于谷歌、微软、苹果等。对编写 WASM 标准的智能合约来说使用 clang/llvm(https://clang.llvm.or

    • 原文:http://zeppelin-solidity.readthedocs.io/en/latest/bounty.html 这个例子结合了Truffle框架,如果你不知道如何集成,可以先看看,还挺方便的:http://me.tryblockchain.org/obust-smart-contracts-with-openzeppelin.html 要为你的合约创建一个赏金项目。需要继承父类B

    • StandardToken继承的父类方法,相比StandardToken,这个类只提供基础功能,而StandardToken允许授权给其它人额度来转发代币。 balanceOf(address _owner) constant returns (uint balance) 返回传入地址的余额。 function balanceOf(address _owner) constant returns

    • 基于FirstBlood的代码:原始的firstBlood的代码在这里。 继承了合约SafeMath,实现了ERC20标准(标准参见:https://github.com/ethereum/EIPs/issues/20)。 原文地址:http://zeppelin-solidity.readthedocs.io/en/latest/standardtoken.html 源码地址:https://g