这是我们将直接从地道的博客系列中的第一个博客,深入探讨了当前我们正在与《议定书》一起做的一些事情的技术细节。

今天的文章来自Alex Pinto,这是Aventus区块链工程团队的最新成员,他在过去的几周中一直在努力加快使用Solidity的速度,并将带给我们一些语言的挑战和特殊性。

今天,我为您提供有关使用Solidity语言进行以太坊区块链编程的文章。 我不会遵循任何计划:我的目标只是写关于学习这种语言的障碍以及我在日常工作中遇到的实际困难。

我想自由地写任何主题,而不必先介绍初级材料,就像我在写教科书时要做的那样。 如果您发现我在谈论我以前没有解释过的事情,那是设计使然。 在下面给我留言,我将在以后的文章中再次与他们联系。

基本访问

今天,我想谈谈Solidity中的字符串。 首先,坚固性在语法上类似于Javascript和其他类似C的语言。 因此,以几种常见和广泛使用的语言之一为基础的新手很容易快速了解Solidity程序的功能。 然而,在隐藏了无法预见的困难的谚语细节中,团结是强大的。 类型string和相关类型bytes就是这种情况。

这两种都是动态数组类型,这意味着它们可以存储任意大小的数据。 类型的变量的每个元素bytes是,勿庸置疑,一个字节。 string类型变量的每个元素都是string的一个字符。 到目前为止还算不错,但最初的外观令人迷惑。 来自其他语言的人可能希望string类型提供一些有用的功能,例如:

  • 确定字符串的长度
  • 在字符串的给定位置读取或更改字符
  • 连接两个字符串
  • 提取字符串的一部分

坏消息:Solidity的string不能执行任何操作! 如果需要以上任何一项,则必须手动进行。

因此,让我们探索其中的一些困难,看看我们可以采取哪些措施。 我打开Remix并在名为string.sol的新文件中键入以下代码。

牢固地处理字符串

屏幕的右侧(在Remix中)由开发人员区域占据。 在“ 编译”选项卡中,我选中“ 自动编译”选项,以便在我编写代码时Remix会通知我错误和代码分析警告。 静态代码分析是通过在标签分析的选项控制,我通常选择的所有选项。

牢固地处理字符串

在当前情况下,Remix将报告两种相同类型的警告:我编写的方法可能会产生高至无限的汽油成本。 我将在这篇文章中忽略它。

上述合同非常少。 它定义了类型为string的状态变量store ,设置它的方法和获取它的方法。 让我们测试一下。

在“ 运行”选项卡中,单击“ 部署” ,如果合同没有问题,该按钮下方将出现一个新区域,其中包含合同所在的地址和可用功能。

牢固地处理字符串

在工作区下方,Remix显示了交易结果的详细记录。 最初,它仅显示一行指示部署合同的帐户,所调用的合同和方法String.(constructor)String.(constructor)以及传递给执行的以太币的数量(最初在Wei中显示,即以太的最小单位,对应于10 ^ -18以太)。 我们可以通过单击标题,显示日志,执行和交易成本,可用天然气,最终结果等来扩展它。

牢固地处理字符串

在这一点上,我只想按下右侧的getStore按钮,并注意其下方如何显示结果:

牢固地处理字符串

同样,左侧还有一个新的事务日志,单击它可以看到:

牢固地处理字符串

在解码的输出中。 一切都很好。

现在,我在setStore右侧的文本框中键入“ 0123456789”,然后单击该按钮。 然后,我再次调用getStore并收到该字符串。 竖起大拇指,我们可以使用字符串进行基本的存储/检索!

现在让我们去做更多有趣的事情。

创建新字符串:数据位置

到目前为止,我已经访问了文字字符串,并且我们看到了如何通过分配它来对其进行更改。 但这只是处理字符串的一种非常粗略的方法。 让我们逐字符创建一个字符串。 这将向我们介绍Solidity编程的一个特殊之处:数据位置。

我创建了一个新方法,该方法仅返回带有三个特定字符的新字符串:“ Abc”。

牢固地处理字符串

这是一个很好的尝试,但是没有用。 重新混音足以立即指出4个错误和1个警告:

其中两个在同一行: string newString = new string(3);

  • 警告:变量被声明为存储指针。 使用明确的“存储”关键字来使此警告无效。
  • TypeError:类型字符串内存不能隐式转换为预期的类型字符串存储指针

其他三个出现在以下各行中,例如newString[0] = "A"; 并且都是相同的类型:

  • TypeError:无法对字符串进行索引访问。

要了解第一个问题,我必须告诉您有关数据位置的信息。 写入区块链非常昂贵。 运行事务的每个节点都必须执行相同的编写,这使事务更昂贵,区块链也更大。 当节点下载包含此事务的数据块时,由于进行此编写,将导致更大的存储成本。 在以太坊中,每笔交易都有一个相关的成本,称为gas ,以激励程序员尽可能经济。

编写合同时,作者可以选择使用哪种类型的数据: 内存便宜(即,它消耗的气体相对较少),但数据易失且在函数完成执行后会丢失。 存储是最昂贵的(契约状态是绝对必要的,契约状态必须在函数调用之间保持一致); 还有一个calldata位置(对应于正在执行的函数的堆栈框架中的值)。 这是最便宜的位置,但大小有限。 特别是,这意味着函数的参数数量可能受到限制。

每个数据类型都有一个默认位置。 这来自Solidity 文档

强制数据位置:
外部函数的参数(不返回):calldata
状态变量:存储
默认数据位置:
-函数的参数(也返回):内存
-所有其他局部变量:存储

注意其细微之处:默认情况下,函数参数存储在内存中,除非函数是外部函数,在这种情况下,它们将存储在堆栈中(即calldata)。 这意味着,一个功能是完全正常的,当public提出的时候会突然有太多的变元的TS external

现在,让我们回到我们的代码并检查该行

string newString = new string(3);

这是函数内部的局部变量,因此默认情况下它在存储区中。 new关键字用于指定内存动态数组的初始大小。 内存阵列无法调整大小。 另一方面,我们可以通过更改存储动态数组length属性来更改其大小,但不能对其使用new

这是我们错误的根源。 在这种情况下,我们要做的就是创建该字符串并将其返回到外部。 让外部世界决定如何处理它,以及它是暂时的还是足够重要才能持久存在于区块链上。 在此示例中,存储并不重要,该字符串将在内存中创建。 为此,我们在声明中添加memory关键字,如下所示:
string memory newString = new string(3);

直接访问字符串:与字节等效

现在让我们看看第二种错误。 这是简单且不可避免的: Solidity当前不允许对string的索引访问 常见问题解答

string 基本上与 bytes 相同, 只是假定保留真实字符串的UTF-8编码。 由于 string 以UTF-8编码存储数据,因此计算字符串中的字符数非常昂贵(某些字符的编码需要多个字节)。 因此,
string s; s.length;
尚不支持,甚至不支持索引访问 s[2]

另一种方法是先将字符串转换为字节,然后直接访问它。 这是可行的,因为string 数组类型,尽管有一些限制。

但是有一个陷阱需要提防。 bytes存储原始数据; string存储UTF-8字符。 以下代码并不总是返回_s的字符数:

牢固地处理字符串

如果_s包含任何用多于1个字节的字符来表示UTF的字符,则会出现此问题。 在这种情况下,该函数将返回输入字符串的字节表示形式的长度,并且该长度将大于字符数。

当尝试寻址字符串的特定字符时,这也会产生影响,因为我们无法预测该字符的字节将位于哪个位置。 我们必须解析字符串以线性标识任何多字节字符,否则请确保将输入限制为固定长度的字符。 例如,如果我们仅使用ASCII字符串,则将是安全的。

回到我们之前的功能,这个工作:

牢固地处理字符串

但是,例如,以下代码尝试将字符串的第三个字符设置为X,当它接收到多字节字符时将失败。

牢固地处理字符串

这将为输入“ Abcdef”返回“ AbXdef”,但返回“XbÁnç!”。 输入“€bánç!”

结论

关于这个话题,还有很多事情可以说,但是这篇文章已经足够长了,所以我会总结一下。 有关类型string的关键概念是这是一个UTF-8字符数组,可以无缝转换为bytes 这是处理字符串的唯一方法。 但是必须注意,UTF-8字符与字节不完全匹配。 在任一方向上的转换都是准确的,但每个字节索引和相应的字符串索引之间没有直接关系。
对于大多数事情而言,将字符串直接表示为类型bytes (避免转换)可能会有一个优势,并且在使用以UTF编码超过一个字节的字符时要格外小心。

现在就足够了。 另一天见,在此编码冒险中有更多步骤。

关于作者

牢固地处理字符串

Alex是Aventus的软件工程师,在区块链工程团队中工作。 他在技术领域拥有20年的经验,并获得了计算机科学博士学位和密码学博士学位。 作为研究的一部分,Alex 发表了有关Kolmogorov复杂性,密码学,数据库匿名化和代码混淆的论文。

Alex还曾在Maia大学学院任教七年,包括指导理学学士学位计算机科学和信息系统与软件的学位课程。

本文最初发布在他的博客上

关于安万特

牢固地处理字符串

Aventus是基于区块链的协议,可为现场票务行业提供增强的信任度,安全性和控制力,实际上消除了伪造票证和不公平的交易。 组织者可以创建,管理和促销其事件和相关票证,显着降低平台成本,并显着影响二级市场。

有关更多信息,请访问 Aventus.io 并在 Twitter, ******** Reddit 上关注Aventus

From: https://hackernoon.com/working-with-strings-in-solidity-c4ff6d5f8008

相关文章:

  • 2022-01-18
  • 2021-11-18
  • 2021-06-18
猜你喜欢
  • 2021-04-08
相关资源
相似解决方案