5.4.2 模块

Reach 源文件是一个规定 Reach 模块的文本文件。通常以 rsh 作为后缀,例如:“ dao.rsh ”。

模块以 'reach 0.1'; 开头,跟随着一系列导入标识符定义。只有包含一个或多个导出的模块才能被编译或使用。

阅读关于版本的导览章节,理解 Reach 怎样通过这种形式使用版本号。

5.4.2.1 语句

任何对计算有效的语句都对模块有效。但也允许一些额外语句。

5.4.2.1.1 导出

模块级别的标识符定义可以通过在他们前面添加 export 来进行导出。例如:

  1. export const x = 1;
  2. export const [a, b, ...more] = [ 0, 1, 2, 3, 4 ];
  3. export function add1(x) { return x + 1; };

是有效导出

模块级别的标识符也可以在定义之后进行导出,并且可以在导出时重命名。例如:

const w = 2;
const z = 0;
export {w, z as zero};

来自其他模块的标识符,即便没有被导入到当前模块,也可以重新导出(并且重命名)。例如:

export {u, x as other_x} from './other-module.rsh';

在给定模块中被导出的标识符,可以被其他模块导入

导出也通过 getExports 向前端开放。函数只有在类型化时,即要用 is 构造才会被开放。

5.4.2.1.2 导入

import 'games-of-chance.rsh';

模块 X 包含一个写为 "LIB.rsh";import 的导入时,“ LIB.rsh ”的路径必须解析到另一个 Reach 源文件中。定义为“ LIB.rsh ”的模块中的导出,会被包含在 X 的绑定标识符集合中。

import {flipCoin, rollDice as d6} from 'games-of-chance.rsh';

导入语句可以限制或是重命名被导入的标识符

import * as gamesOfChance from 'games-of-chance.rsh';

导入可以选择将整个模块绑定到单个标识符,该标识符是一个对象,其字段与该模块导出对应。

循环导入是无效的。

给定导入的路径不能通过包含 .. 来指定当前目录之外的文件,也不能使用绝对路径。

必须使用相对路径,该路径相对于包含这些给定导入的源文件的父目录进行解析。

5.4.2.2 表达式

任何对计算有效的表达式都对模块有效。但也允许一些额外表达式。

5.4.2.2.1 Reach.App
export const main =
  Reach.App({}, [Participant("A", {displayResult: Fun(Int, Null)})], (A) => {
    const result = 0;
    A.only(() => { interact.displayResult(result); })
    return result;
  });

Reach.App 是一种能够接受三个参数的函数:optionsparticipantDefinitions, 和 program

options 必须是一个对象,它支持以下几个选项:

deployMode 'constructor'(默认)
或者 'firstMsg'
决定合约是单独部署('constructor')还是作为首个发布('firstMsg')的一部分部署。如果作为首个发布的一部分部署,则首个发布必须先于所有 wait.timeout 的调用。请参阅部署模式指南了解关于为什么选择特定模式的探讨。
verifyArithmetic truefalse(默认) 决定算术运算是否自动引入 .UIntmax 不会溢出的静态断言。由于验证过程非常繁冗,因此默认 false 。我们建议在最终部署之前将其打开,但在开发期间将其关闭。当选项为 false 时,连接器将确保溢出不会在网络上实际发生。
verifyPerConnector truefalse(默认) 决定是对每个连接器进行验证,还是对常规连接器进行一次验证。若选择 true ,那么类似 .UIntmax 这种归属于连接器的常量,将被实例化为具体数字。这些常数的具体化会导致验证器的性能下降。
connectors [ETH, ALGO](默认) 连接器元组,意味着应用程序需要被编译为该元组内的连接器。默认情况下,会选择所有可用的连接器

participantDefinitions 参数是参与者构造函数的元组。

program 参数必须是符合语法规范的箭头表达式。此箭头的参数必须与 participantDefinitions 的参数数量和顺序一致。函数主体部分是需要被编译的程序。它明确规定了一个步骤,这意味着其内容是由步骤决定的。当它返回时,也必须在一个步骤中;意思是它的内容不能在同一个共识步骤中结束。

如果 .ReachApp 的结果最终绑定了一个导出的标识符,它可能是编译给定的目标,正如在用法章节所讨论的。

5.4.2.2.2 参与者构造

参与者构造函数用于在 Reach 程序中声明逻辑参与者。参与者参与者类可分别用

Participant(participantName, participantInteractInterface)

ParticipantClass(participantName, participantInteractInterface)

进行声明。

participantName 是一个字符串,表示生成的后端代码中参与者函数的名称。每个 participantName 都必须是唯一的。

participantInteractInterface 是参与者交互接口,它是一个对象,其字段均是函数或值的类型,且必须由前端提供给后端,以便与参与者交互