Flow Community Rewards are here. Earn points for engaging in the ecosystem, spend points on prizes. Learn more.
开发者生态
2020年11月10日
使用Ruby与Flow互动
流程
使用Ruby与Flow互动

使用Ruby与Flow互动 作者 丹尼尔-波达鲁

在这篇文章中,我们将探讨如何使用Ruby编程语言与Flow进行交互。这篇文章也可以作为一个很好的例子,说明你可以利用任何还没有Flow SDK支持的编程语言与Flow进行交互,从而大幅度地扩大你的选择范围。

这篇文章的代码可以在Github上找到。

终端/命令提示符

在MacOS上使用终端或在Windows上使用命令提示符来运行命令。

茹比

在开始之前,检查你是否安装了Ruby。在终端,运行以下命令。

ruby -vruby
2.7.1p83

如果你没有安装Ruby,你可以从https://www.ruby-lang.org,安装它。

项目文件夹

为你的项目建立一个新的文件夹。

cd~
mkdir flow-ruby

gRPC和协议缓冲区

我们将使用gRPC协议缓冲器与Flow节点互动。

协议缓冲区是谷歌的语言中立、平台中立、可扩展的机制,用于序列化结构化数据--想想XML或JSON,但更小、更快、更简单。

gRPC是一个基于协议缓冲区和HTTP2的RPC框架。

安装grpcgrpc-toolsjson gem

gem 安装 grpc grpc-tools json

流量协议缓冲区的定义

从GitHub上克隆Flow的存储库。

在终端,运行以下命令。

cd ~
git clone https://github.com/onflow/flow

从Flow的.proto文件中生成Ruby代码。

在终端,运行以下命令。

cd flow/protobuf
grpc_tools_ruby_protoc --proto_path=. --ruby_out=ruby/ --grpc_out=ruby/flow/**/*.proto

将新生成的flow文件夹从protobuf/ruby/复制到flow-ruby.在终端,运行以下命令。

cp -r ~/flow/protobuf/ruby/ ~/flow-ruby/

列出flow-ruby文件夹的内容,确保flow文件夹被复制。在终端,运行以下命令。

cd ~/flow-ruby
ls flow

红宝石代码

启动你最喜欢的IDE,创建一个名为flow.rb的新文件。

flow.rb文件中添加以下代码。

require 'flow/access/access_services_pb'
require 'flow/execution/execution_services_pb'
require 'json'

class Flow
# 1
def initialize(node_address)
@stub = Access::AccessAPI::Stub.new(node_address, :this_channel_is_insecure)
end

# 2
def ping
req = Access::PingRequest.new
@stub.ping(req)
end

# 3
def get_account(address)
req = Access::GetAccountAtLatestBlockRequest.new(address: to_bytes(address))
res = @stub.get_account_at_latest_block(req)
res.account
end

# 4
def execute_script(script, args = [])
req = Access::ExecuteScriptAtLatestBlockRequest.new(
script: script,
arguments: args
)
res = @stub.execute_script_at_latest_block(req)
parse_json(res. value)value)
end

private

# 5
def parse_json(event_payload)
JSON.parse(event_payload, object_class: OpenStruct)
end

# 6
def to_bytes(string)
[string].pack('H*')
end

# 7
def to_string(bytes)
bytes.unpack('H*').first
end
end

Flow类是对从协议定义中生成的代码的封装。

  1. initialize将在我们实例化Flow类时被调用。
    Access::AccessAPI::Stub是由协议定义为我们自动生成的类的名称。我们创建一个新的实例,传递一个Flow访问节点的地址。该对象提供了允许调用访问节点的方法。
  2. ping方法允许ping Flow Access节点,看它是否活着。我们创建一个新的 ping 请求。Access::PingRequest,并在ping方法的调用中传递它。@stub.ping(req)。
  3. get_account(address) 方法允许在Flow网络上获取一个地址的信息。我们使用Access::GetAccountAtLatestBlockRequest.new创建一个获取地址信息的请求,并使用@stub.execute_script_at_latest_block(req)在最新的区块执行该请求。
  4. execute_script方法允许执行一个Cadence脚本。同样,我们创建一个请求对象并执行该请求。
  5. parse_json 是一个实用的方法,用于将脚本的响应解析为一个结构。
  6. to_bytes是一个实用的方法,它可以将一个Flow地址从字符串转换为字节数。
  7. to_string是一个实用方法。我们没有在其他方法中使用它,但如果你想从一个Flow账户中读取代码字段,它是很有用的。

流动仿真器

Flow模拟器是一个轻量级的工具,可以模拟真实Flow网络的行为。

我们将使用模拟器来测试Ruby客户端。按照这些步骤来安装模拟器。

启动Flow模拟器。在一个单独的终端窗口,运行以下命令。

流动仿真器启动

与流互动

启动Ruby REPL并调用flow.rb文件。

在终端,运行以下命令。

irb -I .-r flow.rb

在你启动REPL的终端窗口中,运行以下命令。

f = Flow.new("127.0.0.1:3569")
f.ping
< Access::PingResponse: >

我们ping了Flow仿真器,它成功地作出了回应。

获取现有账户的信息

要用现有的Flow地址进行测试,在启动Flow模拟器的终端窗口中查看,并使用服务账户的地址。

运行以下命令。

a = f.get_account('0xf8d6e0586b0a20c7')

< Entities::Account: address: "\xF8\xD6\xE0Xk\n \xC7", balance: 0, code: "", keys: [<Entities::AccountKey: index: 0, public_key: "av+?\xD6\xD9NEg\x01\x93\x8CCC*\x89\x941g:\xA7Y\x05\xA9\vP\xFC\xF0\xAFN\xDD\xAEE]\x13\xF99A\xAF\x120)y\xAD\xCAa\xC0\x8E\xDF]hY\xDC\x15\x82\xA2\x96DK\xCBF\xC2\xFBB", sign_algo: 2, hash_algo: 3, weight: 1000, sequence_number: 0>]>

响应显示关于地址为Flow账户的信息。0xf8d6e0586b0a20c7。

数据显示为字节,我们可以用 unpack('H*').first将其解码为一个十六进制字符串。

a.地址
"\xF8\xD6\xE0Xk\n\xC7"

a.地址.unpack('H*').first
"f8d6e0586b0a20c7"

a.余额
0

a.key.first.public_key.unpack('H*')first
"61762b3fd6d94e456701938c43432a899431673aa75905a90b50fcf0af4eddae455d13f93941af12302979adca61c08edf5d6859dc1582a296444bcb46c2fb42"

我们可以看到,该账户的余额为0,目前有一个公钥被授权访问它。

执行一个Cadence脚本

脚本是一个只读的Cadence片段,用于查询区块链的计算状态。

运行以下命令。

script = 'pub fun main(): Int { return 1 }'
result = f.execute_script(script)

result.type
"Int"

result.value
"1"

脚本是一个简单的Cadence脚本,返回1。

脚本是由execute_script函数执行的,其结果可在结果变量中获得。

访问和执行API

流量访问节点和流量执行节点提供的方法更多。

探索flow/access flow/executionflow/entities文件夹中的方法定义。

交易

一个交易是一个Cadence片段,它被执行以更新区块链的计算状态。一个交易可以更新一个或多个签名账户的存储。

执行交易的代码已经在flow/execution文件夹中生成,但对交易的有效载荷进行加密签名所需的代码不能从.proto定义中生成,必须实施。在一个安全的环境中,签名将由硬件安全模块(HSM)处理,它能够安全地存储私钥。如果你对从Ruby中签署交易感兴趣,你将需要自己编写这一部分。

首先,你需要安装rlp opensslgem。接下来,在将代码移植到Ruby之前,你需要看一下Go SDK中的签名实现,以了解签名的工作原理。

总结

如果您使用的编程语言尚未有Flow SDK,您仍然可以使用该语言与Flow进行交互。协议缓冲区是语言中立和平台中立的,因此你可以从任何编程语言的协议定义中生成代码。

我们在这篇文章中写的Ruby代码可能是Ruby版Flow SDK的开始。我们鼓励你加入Discord上的Flow社区,在那里你可以和其他开发者一起用你喜欢的编程语言构建Flow SDK。