迈克尔逊干涉仪仿真程序
我们将使用用户传入的参数在Michelson中编写一个新的智能合约,在将新字符串保存到存储中之前,我们将其连接到存储中已经存在的字符串。
(第1部分 在这里 。)
在上一篇文章中介绍了迈克尔逊的基础知识之后,我们将继续对这种编程语言的探索。
在这个新的部分中,我们将介绍一个很棒的工具,它将帮助我们编写,调试和检查我们的迈克尔逊代码:由Baking Bad团队开发的带有迈克尔逊内核的Jupyter笔记本 。
我们将使用用户传入的参数在Michelson中编写一个新的智能合约,在将新字符串保存到存储中之前,我们将其连接到存储中已经存在的字符串。
强烈建议先阅读第1部分 ,因为它介绍了我们将在此处使用的Michelson中有关智能合约的概念。
但是首先,让我们看一下可能最好的编码工具:Michelson!
Baking Bad的Jupyter笔记本
Baking Bad开发了一个在线Michelson编译器,它不仅可以编译您的Michelson代码。
它提供语法高亮显示,调试和堆栈的逐步可视化。 您可以使用此链接打开我们将用于本课程的笔记本(请记住,内核需要一两分钟才能加载),然后再选择MichelsonTutorial-Demo3.ipynb
文件。
该文件分为两部分:
内联代码
在第一部分中,整个智能合约都放入一个单元格中。 您可以通过在以下单元格中写入RUN
%default
parameter storage
来编译和运行它。
运行智能合约后,有每个步骤的详细说明以及每个指令对堆栈所做的修改(在图片的In [10]
)。 在运行时结束时(如图中的Out [10]
),您将得到新的存储。
分步代码
该编译器的亮点在于,您可以输入说明一步一步地修改堆栈,并在每个步骤之后检查其效果。
与每个迈克尔逊智能合约一样,您首先要指定参数和存储。 然后,键入BEGIN
parameter storage
以开始执行。
完成此配置步骤后,您可以一个一个地输入说明,并通过按CMD/CTRL + SHIFT
来查看说明如何修改堆栈。 在Out [...]
单元格中,当前值显示在堆栈顶部。
注意:您可以在分步代码中看到DUMP
指令。 这不是 Michelson,这只是Jupyter笔记本中用于打印堆栈当前状态的指令。
当您想结束智能合约的执行时,请输入COMMIT
,如果代码没有错误,它将返回新的存储。 如果执行的任何步骤都有一个,您将看到一条消息,并能够立即对其进行修复,而不必逐行查看代码。
迈克尔逊智能合约中的参数处理
在上一课中,我们介绍了一些指令,这些指令可以操纵堆栈中已经存在的数据,也可以推入自己的位置。 但是如何处理用户的输入呢? 这实际上很容易!
我们将使用上面介绍的Jupyter笔记本中存在的合同。 欢迎您继续阅读笔记本并逐一运行说明,以更好地了解每条说明后的堆栈外观。 这是完整的智能合约:
如果您还记得的话,调用合同时,包含参数和存储空间的一对将自动推入堆栈的顶部。 然后,我们可以获取该对的左侧部分(参数)并使用它。 运作方式如下。
首先,让我们初始化堆栈:
在这一步中,我们得到含类型的参数一对新的堆栈string
( world
)和类型的存储string
,太( Hello
)。 我们的最终目标是连接这两个字符串并返回它们。
在下一步中,我们复制堆栈的顶部元素,因为我们需要将参数和存储空间放在堆栈的两个单独的元素中,以便能够将它们放在一个字符串中。
迈克尔逊(Michaelson)没有变量,并且天生就不可变。 可以使用不同的方法来创建堆栈的新元素,例如,通过推入它们(使用PUSH
指令)或复制它们(使用DUP
指令)。 请记住,在执行的每个步骤中,您都在处理堆栈的顶部元素。 这是您唯一可以使用的工具。
让我们从堆栈的第一个元素开始,让我们从该对中获取参数。 我们使用CAR
指令,其目的是破坏类型pair
的元素并返回该pair
的左侧(在这种情况下,该参数传递给智能合约)。 运行CAR
,我们将字符串world
放在栈顶。
现在您可能想知道:如果Michelson仅处理第一个元素,我该如何处理堆栈的第二个元素? 非常简单! 使用SWAP
指令将第二个元素放在顶部,并保留另一个元素供以后使用。
使用SWAP
指令时,您告诉Michelson:“目前我不需要第一个元素,但是我想处理第二个元素。” 迈克尔逊会将第一个元素降低到第二个位置,将第二个元素降低到第一个位置。
现在,我们在开始处复制的第二对在顶部,我们可以使用反向CAR
通过CDR
指令获得该对的正确部分。
CDR
指令的工作方式类似于CAR
指令,但是您将保留所操作对的右侧(一对始终仅包含两个元素,因此CDR
和CAR
是唯一可能的操作)。 之后,您可以看到我们的堆栈由两个元素组成:第一个位置为字符串Hello
,第二个位置为字符串world
。
现在让我们把它们放在一起!
在计算机编程中,将两个字符串放在一起的操作称为串联 。 在迈克尔逊中将两个字符串放在一起的指令被称为CONCAT
是合乎逻辑的。 该操作采用当前位于堆栈顶部的两个字符串,并返回单个字符串。 为了使操作成功,必须满足两个条件:
- 您确实在堆栈的顶部有两个元素(如果仅剩一个元素,它将产生一个错误)。 如果存在更多元素,则只会处理顶部的两个元素。
- 堆栈顶部的两个元素是字符串(Michelson是严格键入的,它知道堆栈中具有什么样的值,因此,甚至不要试图愚弄它)
现在,如果您还记得我们在第1部分中讨论的内容,那么您将知道会发生什么。 我们必须创建一个带有列表和新存储的配对,以终止智能合约的执行(这就像在Michelson中说再见)。
首先,让我们在堆栈顶部推送一个空列表:
一旦存在空列表,我们就可以使用空列表和字符串创建一个对:
再次提醒您,要警惕元素的顺序及其类型:Michelson将把第一个元素放在对的左侧,将第二个元素放在对的右侧。 返回一对类型(对字符串列表(操作))将产生错误。
现在我们的堆栈是干净的,并包含一对带有操作列表和字符串的对,智能合约的执行结束。
您可以在下面的视频中看到堆栈的完整执行和转换:
结论
在面向初学者的迈克尔逊教程的这一新部分中,我们介绍了带有迈克尔逊内核的Jupyter笔记本,我们将在本教程的以下部分中大量使用它来编写,调试和执行代码。
引入了迈克尔逊(Michelson)中的新操作代码: CAR
,提取一对货币对的左侧部分; DUP
,它复制堆栈的顶部元素; CDR
,提取一对的正确部分; SWAP
,交换两个元素在堆栈顶部的位置; 和CONCAT
,它接受两个字符串,并返回由前面两个字符串组成的单个字符串。
还添加了表示堆栈中操作的动画,以帮助您更好地可视化并跟踪每个步骤发生的情况。 当堆栈中的操作变得更加复杂和复杂时,这将变得更加有用。
敬请关注!
(以前在付费专栏后面发布过:https://medium.com/better-programming/an-introduction-to-michelson-the-scripting-language-of-tezos-part-2-4cc972c8237c)
迈克尔逊干涉仪仿真程序