如何在UML中对智能合约建模?

时间:2018-08-24 08:33:22

标签: uml solidity smartcontracts

我正在寻找一种使用诸如UML之类的建模语言对以太坊智能合约交互进行建模的方法。

我有以下保密合同:

CLLocationManager

我使用该类图对其进行了建模,对吗?

enter image description here

3 个答案:

答案 0 :(得分:4)

您只是与这三个类有关联:

enter image description here

(我只是画了一个关系)

右边的角色名称与点一起告诉它是左边的类的拥有的属性。不确定可见性(如果默认情况下是私有的,则将+替换为-)。

答案 1 :(得分:2)

[编辑以供进一步说明]

对系统建模是使用建模语言以正式方式描述它,在某些情况下,遵循一些通用准则。在这种情况下,您建议使用UML(请参见UML Specification)。

UML图可以分为三类:

  • 结构:常见的结构,值,分类器和程序包都在此类别中
  • 行为:常见的行为,动作,状态机,活动和交互属于此类。
  • 补充:用例,部署和信息流在此类别中。

作为建模者,您需要确定要应用的目标所需的图。

在您的问题中,您说您正在寻找一种对交互进行建模的方法。这属于行为类别。但是,您在结构类别中提供了示例代码和建议的类图。

话虽如此,您建议的图表是否正确?我会说这是不准确和不完整的(但不一定是不正确的)。让我进一步解释一下。

在建议的图中,您有四个类别:ServiceContractStorageContractQuizContractSignatureContract。您已在类之间绘制了一种关系,称为 dependency 。这种依赖关系具有特定的类型:用法(由«use»关键字表示)。在UML中这意味着什么?

UML中的依赖关系被定义为一种关系,其中“ 没有供应商,客户的语义就不完整”(UML规范的第7.7.3.1节) 。此外,使用依赖关系被定义为一种关系,其中“ 一个NamedElement需要另一个NamedElement(或一组NamedElements)以实现其完整实现或操作”(第7.7.3.2节

因此,如果我们将这些定义应用于您建议的图表,则您可能会阅读ServiceContractStorageContract之间的关系,因为“ ServiceContract使用StorageContract”。但没有别的。使用此图,您不知道ServiceContract如何使用StorageContract,如果它使用多个StorageContract实例,依此类推。

由于您知道这些类之间的关系,因此应该使用更准确和完整的图表。

第一步是使用关联而不是依赖性。在UML中,关联被定义为“ 在类型实例之间可能发生的语义关系”。并且您知道在类图中正在建模的类之间的语义关系。因此,使用关联会更有意义。

关联 用实线表示(实际上,UML规范说可以绘制为菱形,但是对于二进制关联,它通常表示为用实线绘制)。因此,让我们开始将图表更改为新图表。在下图中,您可以看到四个具有关联关系的类(仍然不完整):

enter image description here

现在有了关联,我们需要进一步定义它。协会有名字吗?可以以两种方式读取关联吗?我们知道关联两端的多重性值吗?协会的两端是否有矛盾?

在此示例中,我们不需要关联的名称,似乎可以以两种方式读取关联,并且多重性值在所有末端均为1。然后,我们不添加任何与这些问题有关的图表。但是约束呢?

让我们看一下源代码。当您放置此内容时:

contract ServiceContract {
    constructor (address _storeC, address _quizC, address _signC) {
        StorageContract storeC = StoreContract(_storeC);
        QuizContract quizC = QuizContract(_quizC);
        SignatureContract signC = SignatureContract(_signC);
    }
}

您可以将其表示为“ ServiceContract具有(拥有)名为storeC的属性,该属性的类型为StoreContract ”,依此类推。关联中的所有权由一个小的实心圆(称为 dot )表示,该直线与所拥有的Classifer相交。您也可以添加拥有所有权的属性的名称(第11.5.4节)。此时,该图是这样的:

enter image description here

(请参见the answer from Thomas Kilian

由于我们无法从源代码推断属性的可见性,因此我们可以将其设为未定义(否则,可以在公共名称的属性名称之前使用+符号{{1 }}代表私有财产,-代表受保护财产,#代表包裹)。

我们还可以在~的分类器中显示属性,而不是在关联中拥有的分类器的末尾显示属性。看起来像这样:

enter image description here

UML规范(第9.5.3节)允许两种样式,并且也不强制执行任何约定。但是,它提到了常规建模场景的约定”,即类型为一种Class的属性是Association端,而类型为DataType的属性不是”。

该图符合UML规范,并且描述了您拥有的系统,因此是正确的。

  • 名为ServiceContract的分类器,具有三个属性:
    • 名为ServiceContract的属性,其类型为名为storeC的分类器。
    • 名为StorageContract的属性,其类型为名为quizC的分类器。
    • 名为QuizContract的属性,其类型为名为signC的分类器。

请记住,作为建模者,这是否足以满足您的目标是您的选择。

从源头上我可以说上一张图仍然不完整且不准确。为什么?

  • 因为源包含图中未表示的三个操作(功能)。可以在完整性方面进行改进。
  • 因为您无法从图中说出SignatureContract拥有的分类器是否被拥有以将一组拥有的分类器的实例组合在一起。在这种情况下,是否拥有的分类器共享相同的范围。可以提高准确性。

首先,我们将把操作(功能)添加到图中:

enter image description here

[注意:您也可以将_constructor_添加到操作中。]

我猜这些函数是公共的,因此我在每个操作名称的开头都包含了ServiceContract修饰符。

为了准确起见,在我看来+ServiceContractStorageContractQuizContract分组在一起,以便提供通用的分类器来访问某些操作(功能)。如果真是这样,那么我们在谈论的是聚合。在UML中,聚合定义为一种关联,其中“使用一个实例将一组实例分组在一起”(第9.5.3节)。

聚合可以分为两种类型:共享(或者在规范的先前版本中通常称为 aggregation )和 composite (或在规范的早期版本中通常称为 composition )。

UML规范或多或少地提供了某种语义,以表示聚合类型为 composite 的含义:“ 复合对象负责存在和存储对象。组成的物体”。

让我们说,在您的情况下,SignatureContractStorageContractQuizContract存在和存储SignatureContract的责任。那么在这种情况下,您有一个复合聚合,用黑色菱形表示:

enter image description here

它被读为“ ServiceContract由分类器类型ServiceContract的自有属性,称为StorageContract ”,依此类推。

请记住,使用复合类型的聚合,您是说storeC对象负责存在和存储。这意味着无论何时{/ {1}}的实例被删除/销毁,相关的ServiceContractServiceContractStorageContract也必须被销毁。

如果不是这种情况,并且鉴于关联仍与聚合定义匹配,那么唯一可用的其他选择是必须共享。 UML规范没有明确提供 shared 聚合的确切语义,而使应用程序区域和建模者具有提供这些语义的责任。

因此,如果QuizContractSignatureContractStorageContract独立于QuizContract存在,并且如果您同意SignatureContract汇总这些根据UML规范中定义的对象,您必须使用共享聚合。

共享的 聚合由分类器关联末尾的空心菱形表示,聚合其他分类器。这就是它的样子:

enter image description here

此图可以读为:

  • 有四个分类器:ServiceContractServiceContractServiceContractStorageContract
  • QuizContract汇总了三个拥有的属性:
    • SignatureContract,类型为ServiceContract
    • storeC,类型为StorageContract
    • quizC,类型为QuizContract
  • signC有一个需要三个参数的构造函数:
      类型为SignatureContract
    • ServiceContract
    • 类型为_storeC
    • address
    • 类型为_quizC
    • address
  • _signC具有三个公共功能:
    • address,它需要一个类型为ServiceContract的自变量storeData,但不返回任何内容。
    • bytes32,它需要一个名为data的类型getAnswer的参数,并返回bytes32数据类型。
    • question,它需要一个bytes32类型的名为data的参数,并返回一种sign数据类型。

请记住,对于您想要的目标,此最终图表可能太详细了。作为建模者,您有责任决定是否在图表中包括或不包括一些细节。

答案 2 :(得分:0)

虽然花一些时间了解应该为 UML 中的特定 Solidity 关系(inheritance、组合等)使用什么确切的箭头可能是件好事,但总体趋势是让标准工具来关注这一点。

>

有sol2uml UML生成器https://github.com/naddison36/sol2uml

已在 https://etherscan.io 上使用

例如USDT https://etherscan.io/viewsvg?t=1&a=0xdAC17F958D2ee523a2206206994597C13D831ec7 (见下图)

所以不要花时间手动绘制线条,使用更明智的工具为您更快地完成。