本文是有关协议和网络技术方面的Gravity文档的一部分,它提供了一个基于示例的全面的概述。本文以Ethereum和BSC集成为例,演示了开发人员在将新的区块链集成到Gravity跨链网络中时可能遇到的情况。
写扩展程序
为了通过增加对新区块链的支持来扩展Gravity协议,在Gravity-Tech / gravity-core和本文中提到的其他一些Github存储库中将进行一系列提交是被支持和鼓励的。这些源修改可以分为四个部分:
-
Gravity分类帐节点逻辑(适配器)
-
Gravity Oracle逻辑
-
Gravity 核心合约(Gravity-Tech / gravity-core / contracts)
-
Gravity部署器(Gravity-Tech / gateway-deployer)
强烈建议您在实施解决方案时在指南中提到的特定存储库中打开拉取请求,这可以尽量减少对现有代码库的重写。如果您的目标是在新的集成链之上支持应用层逻辑,则需要对Gravity-Tech / gateway进行一些更改。逻辑部分还包括编写适当的USER-SC(用户智能合约)。
SuSy是第一个基于Gravity构建的alpha产品,它是跨链网关的协议和接口。当前,它以Waves为起点,以Binance Smart Chain为终点。SuSy主网Alpha位于susy.gravity.tech上,并提供一个前端接口,该接口允许用户将USDN令牌从Waves交换到BSC中。BSC上的USDN具有与以太坊上USDN相同的功能,包括自动抵押,弹性供应以及自动在所有持有人之间分配的抵押奖励。
SuSy协议
SuSy协议基于对oracle的信任,oracle是将信息从一个区块链传输到另一个区块链的中介。从技术的角度来看,当将oracle实现为Gravity协议所做的不信任的分散式系统时,基于它的跨链网关将继承不信任。通过Gravity oracle协议实现的SuSy协议的另一个功能是存在有用的高级抽象和服务。
此外,要进行令牌从一个区块链到另一个区块链的跨链交换,除了相应区块链网络的本机原生令牌之外,不需要其他令牌。
以下是SuSy跨链传输算法的说明。它显示了令牌从起源链到目的地链的转移,在令牌中它将作为swT(包装)令牌发行并发送到目标链中的接收者R.
用户(S)通过向其转移T令牌的数量(A)并在DESTINATION-CHAIN中指定收件人的公共地址来与LU-PORT智能合约进行交互。网关智能合约自动创建唯一的SWAP-ID并设置注册状态。LU-PORT智能合约冻结了收到的资金。
有关此事件的信息由提取器Extractors(Gravity网络的服务)处理,这些服务处理接收到的数据并将其传达给Gravity。Oracle从Gravity框架将有关新SWAP-ID和交换方向的哈希数据移动到验证合约(NEBULA-SC),在其中验证Gravity网络验证程序的签名和所传输上下文的合法性。
验证后,将调用SEND-DATA-TX事务,其中包含一组数据以及用于向接收方(R)发行和发送swT令牌的指令。
同样,有关此事件的所有数据都由Gravity网络oracle处理,并且,如果成功执行,将设置“已处理”状态。在达到一定数量的分叉可能性最小的块之后,可能需要设置最终状态。
相反,将swT令牌从DESTINATION CHAIN转移到ORIGIN CHAIN并解锁LU PORT合约上的T,过程与上相似。唯一的区别在于最终交易,也就是说,IB PORT上swT令牌的刻录和LU PORT上的T令牌的解锁是相反的。
关于SuSy dApp在其他区块链上的扩展,USER-SC充当IB(Issue-Burn)和LU(Lock-Unlock)端口的角色。USER-SC方法应由NEBULA-SC调用。因此,为了使该协议之上的应用程序正常运行,需要:
-
在Gravity-Tech / gravity-core / contracts内提供新的NEBULA-SC和SYSTEM-SC(重力合同)。
-
创建一个与您的自定义NEBULA-SC一致的自定义USER-SC。
关于扩展Gravity Core的建议
为了确保与新链的兼容性,需要一组单独的智能合约。更重要的是,有两种类型的合约:Gravity core使用的合约和特定于应用程序的合约(例如SuSy)。
在此处可以找到以太坊和海浪的IB端口和LU端口的示例:
· https://github.com/Gravity-Tech/gateway/blob/main/contracts/ethereum/IBPort.sol
· https://github.com/Gravity-Tech/gateway/blob/main/contracts/waves/luport.ride
应该在新的区块链网络中实现两个具有以下功能的新智能合约:
-
智能合约应使用以下参数支持对attachEventData函数的外部调用:令牌ID(可选,因为不同的令牌将具有自己的网关),金额,接收者
-
5个管理员帐户中只有一个可以调用此方法。
-
在attachEventData之后,Receiver必须接收包装的令牌
-
包装的令牌的持有者应该能够将令牌发送到网关地址,这将触发API(RPC)调用。
以上1-4的陈述,必须实现开放和公共的API。
创建合同后,需要将它们编译为字节码。编译后的字节码文件应放在“ / abi”目录中。考虑检查Gravity-Tech / gateway存储库中的“ contracts”目录,以查看网关合同的源代码示例。
为了添加任何新链的实现,首先应由Gravity Network本身进行支持。完成智能合约后,有必要在Gravity Core存储库中实现核心适配器。Gravity Core应用程序的体系结构是模块化的,没有任何紧密的耦合,这保证了扩展单独组件的简便性。原则上,使用任何编程语言或库都是可以接受的,但是通常最好通过提供所需方法的实现来扩展现有的Go源代码,而不是从头开始重写。
若要更清楚地了解对Gravity Core进行的必要更改,请查看此“ BSC support”对Gravity Ledger Node扩展的请求。在本文的后面,我们将说明上面的pull请求中描述的更改的每个部分。
要记住的要点:
· 请注意特定链的BlocksInterval参数(正确的网络“pusation”所需)。
· 包括适配器的实现IBlockchainAdaptor接口,它是每个特定链中最具描述性的部分。
· 尝试启动节点并在customnet中部署合约,以测试新编写的适配器。测试后,创建对Gravity-Tech / gravity-core的拉取请求。
基于BSC和以太坊集成的所需更改概述
cmd / gravity / commands / ledger.go
在createApp()函数中,应提供用于实例化新适配器的构造函数:
可以考虑将适配器实现存储在common / adaptors / [chain_name] .go中。
Common/adaptors/[chain_name].go
与特定链通信相关的重要部分是IBlockchainAdaptor接口:
让我们回顾一下以太坊适配器如何满足接口的要求。
首先,声明特定于区块链的类型和结构:
以太坊实现包含:
-
WithEthereumGravityContract()函数可基于GravityContractAddress进行实例化。它在前面提到的createApp函数中调用。
-
EthAdapterWithGhClient()函数,用于启动Gravity Oracle:
还必须实现一个构造函数,例如下面的NewEthereumAdaptor():
下面来探索GetHeight()和Sign()方法。第一个检索区块链高度,第二个实现字节签名:
WaitTx必须阻塞线程。一个简单的选择模式可以处理需要等待交易的情况。注意:这里使用queryTicker来防止goroutine泄漏,因此3秒超时是硬编码的:
PubKey()解析适配器的公钥。ValueType()使用相应的ABI实例化Nebula-SC。接下来,它调用DataType()来解析星云使用的值类型(Gravity支持Byte,Int和String类型)。
该AddPulse()实现包含许多技术细节。最重要的是,此方法执行:
-
检查Nebula脉冲计数和BFT值是否一直保持为智能合约状态。如果任何值都不存在,则该方法返回一个空字符串。
-
检查是否有正确数量的验证器(> = BFT值)已对消息签名。
SendValueToSubs()方法负责将值发送到Nebula的订阅者。Nebula与订阅者具有一对多关系。
SetOraclesToNebula()更新Nebula的oracle。签名和公钥验证是强制性的:
SendConsulsToGravityContract()类似,但是它用于consuls和Gravity合约的上下文中。
SignConsuls()和SignOracles()负责对更新的consuls/oracle进行签名。两种方法实际上使用相同的算法。
LastPulseId()解析Nebula的最后一个脉冲的ID,这是Nebula oracle执行的最后一个动作的ID。该方法对Gravity Oracle至关重要,因为它通常用于比较当前脉冲和先前脉冲的迭代器中。
LastRound()确定Gravity网络中的最新动作。Round本质上是区块链高度的特定指标,其中Gravity网络通过Oracle/Consuls更新,值更新或脉冲发送来使状态发生变化。
RoundExist()验证是否存在特定回合。
common / account / chain.go
在此文件中,应实例化一个常量。在其他地方,当提及现有常量时,也应添加此新常量:
Common/account/nebula.go
该模块负责Nebula逻辑。
common / account / pubkey.go
在此指定与帐户地址实例化有关的链行为。
common / storage / consuls.go
此模块负责解析consul密钥。
Oracle组件
oracle / node / node.go
Gravity Oracle的关键部分。node.go以及整个oracle / node模块描述了现有的实现并设置了oracle约束。