使用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和协议缓冲区
协议缓冲区是谷歌的语言中立、平台中立、可扩展的机制,用于序列化结构化数据--想想XML或JSON,但更小、更快、更简单。
gRPC是一个基于协议缓冲区和HTTP2的RPC框架。
安装grpc、grpc-tools和json 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类是对从协议定义中生成的代码的封装。
- initialize将在我们实例化Flow类时被调用。
Access::AccessAPI::Stub是由协议定义为我们自动生成的类的名称。我们创建一个新的实例,传递一个Flow访问节点的地址。该对象提供了允许调用访问节点的方法。 - ping方法允许ping Flow Access节点,看它是否活着。我们创建一个新的 ping 请求。Access::PingRequest,并在ping方法的调用中传递它。@stub.ping(req)。
- get_account(address) 方法允许在Flow网络上获取一个地址的信息。我们使用Access::GetAccountAtLatestBlockRequest.new创建一个获取地址信息的请求,并使用@stub.execute_script_at_latest_block(req)在最新的区块执行该请求。
- execute_script方法允许执行一个Cadence脚本。同样,我们创建一个请求对象并执行该请求。
- parse_json 是一个实用的方法,用于将脚本的响应解析为一个结构。
- to_bytes是一个实用的方法,它可以将一个Flow地址从字符串转换为字节数。
- 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/execution和flow/entities文件夹中的方法定义。
交易
一个交易是一个Cadence片段,它被执行以更新区块链的计算状态。一个交易可以更新一个或多个签名账户的存储。
执行交易的代码已经在flow/execution文件夹中生成,但对交易的有效载荷进行加密签名所需的代码不能从.proto定义中生成,必须实施。在一个安全的环境中,签名将由硬件安全模块(HSM)处理,它能够安全地存储私钥。如果你对从Ruby中签署交易感兴趣,你将需要自己编写这一部分。
首先,你需要安装rlp和 opensslgem。接下来,在将代码移植到Ruby之前,你需要看一下Go SDK中的签名实现,以了解签名的工作原理。
总结
如果您使用的编程语言尚未有Flow SDK,您仍然可以使用该语言与Flow进行交互。协议缓冲区是语言中立和平台中立的,因此你可以从任何编程语言的协议定义中生成代码。
我们在这篇文章中写的Ruby代码可能是Ruby版Flow SDK的开始。我们鼓励你加入Discord上的Flow社区,在那里你可以和其他开发者一起用你喜欢的编程语言构建Flow SDK。