# OFMF跨链对接
# 比特币跨链
对比特币跨链是通过检查接收地址(多签地址)
和OP_RETURN
中的附加信息来确定的。对于OFMF
系统而言,如果检测到交易输出中包含指定的接收地址
,并且在附加信息中解码得到比原地址
,这样便可以确定是一笔跨链请求交易。
跨链交易请求:
{
"jsonrpc":"2.0",
"method":"createrawtransaction",
"id":1,
"params":[
[
{
"txid":"79d2d49cee6a2b37838ac1f2b459f7820a4efdfb91a0d20417b835ae10dea801",
"vout":0
}
],
[
{
"2N5KvkLV9JzEqVeLpc7tG5LB9ZkzXB8xGLh":49 // 多签地址
},
{
"data":"0014ce6cf18e24407480b22fb086358e8071a672f62a" // 附加信息(包含比原的control_program)
},
{
"2NAj8SjSVhZL8iry9fRnzcKgp8VotL3T8R2":0.9 // 找零地址
}
]
]
}
跨链交易响应:
{
"result": "020000000101a8de10ae35b81704d2a091fbfd4e0a82f759b4f2c18a83372b6aee9cd4d2790000000000ffffffff03001110240100000017a91484853295a31883eb9b499f1616d5dfe595ba7650870000000000000000186a160014ce6cf18e24407480b22fb086358e8071a672f62a804a5d050000000017a914bfc128490ae2ee6b91da82fc762445eded61d8ae8700000000",
"error": null,
"id": 1
}
跨链交易详细信息:
{
"result": {
"txid": "3af30005081c1fe084872564ff7e1c75fda617c75f6e80987498ce5a84ac8262",
"hash": "3af30005081c1fe084872564ff7e1c75fda617c75f6e80987498ce5a84ac8262",
"version": 2,
"size": 148,
"vsize": 148,
"weight": 592,
"locktime": 0,
"vin": [
{
"txid": "79d2d49cee6a2b37838ac1f2b459f7820a4efdfb91a0d20417b835ae10dea801",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 49.00000000,
"n": 0,
"scriptPubKey": {
"asm": "OP_HASH160 84853295a31883eb9b499f1616d5dfe595ba7650 OP_EQUAL",
"hex": "a91484853295a31883eb9b499f1616d5dfe595ba765087",
"reqSigs": 1,
"type": "scripthash",
"addresses": [
"2N5KvkLV9JzEqVeLpc7tG5LB9ZkzXB8xGLh"
]
}
},
{
"value": 0.00000000,
"n": 1,
"scriptPubKey": {
"asm": "OP_RETURN 0014ce6cf18e24407480b22fb086358e8071a672f62a", // OP_RETURN + 比原地址对应的control_program
"hex": "6a160014ce6cf18e24407480b22fb086358e8071a672f62a",
"type": "nulldata"
}
},
{
"value": 0.90000000,
"n": 2,
"scriptPubKey": {
"asm": "OP_HASH160 bfc128490ae2ee6b91da82fc762445eded61d8ae OP_EQUAL",
"hex": "a914bfc128490ae2ee6b91da82fc762445eded61d8ae87",
"reqSigs": 1,
"type": "scripthash",
"addresses": [
"2NAj8SjSVhZL8iry9fRnzcKgp8VotL3T8R2"
]
}
}
]
},
"error": null,
"id": 1
}
# 以太坊跨链
以太坊跨链是通过检测多签合约
和比原地址注册合约
两部分来构成的,为了以后兼容以太坊的ERC20
系列币种,跨链到比原上的地址都通过注册合约的形式来获取。要构建一笔跨到OFMF系统的交易,首先需要调用注册合约将自己的发送地址跟比原地址绑定起来,然后再发送以太币ether
到多签合约地址上。因此,用户只需要在第一次跨链的时候完成跨链地址的注册,便可以在以后的跨链过程中重复使用了。对于OFMF
系统而言,如果检测到交易目标地址是多签合约,并且在注册合约中能够找到发送者注册的比原地址,这样便可以确定是一笔跨链请求交易。
转账到多签合约地址
跨链交易请求:(普通转账交易)
{
"jsonrpc":"2.0",
"method":"eth_sendTransaction",
"id":1,
"params":[
{
"from":"0x9ba9ae032a2709efb6eb5651b78058f19f01a38c", // 用户地址
"to":"0xd14cedc448bfcd8cc3e1b94786573bd6fbd5c661", // 多签合约地址
"gas":"0x83bb",
"gasPrice":"0x1caf4ad00",
"value":"0x38d7ea4c68000",
"data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
}
]
}
跨链交易响应:
{
"jsonrpc":"2.0",
"id":1,
"result":"0xab6fb2d09cd0b7dc44eb4de86ef43ad19fba2c82df2a495e5bb9d33f2e80561f"
}
跨链交易详细信息:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"blockHash": "0x7e27fee38b0df028f4322e7ebf95d8f47ed0da7733fa1ddbec779d7aaf6fadce",
"blockNumber": "0x1067230",
"chainId": "0x2a",
"condition": null,
"creates": null,
"from": "0x9ba9ae032a2709efb6eb5651b78058f19f01a38c",
"gas": "0x83bb",
"gasPrice": "0x1caf4ad00",
"hash": "0xab6fb2d09cd0b7dc44eb4de86ef43ad19fba2c82df2a495e5bb9d33f2e80561f",
"input": "0x",
"nonce": "0xdb",
"publicKey": "0x465a7b51942e0617debaefbfdd9b31a049a19b9068f54587e3a5e737ab191c5783c350d335be550c2c674df94095aa26e5f3bf6535a4a75255ad7db4b60b2eaa",
"r": "0x29830089f30076d8be18d91bd26afa8044a51f2b32e88533046c54761ddff844",
"raw": "0xf86c81db8501caf4ad008283bb94d14cedc448bfcd8cc3e1b94786573bd6fbd5c66187038d7ea4c680008077a029830089f30076d8be18d91bd26afa8044a51f2b32e88533046c54761ddff844a0509f817bdcf481fecb526fe686e627287cc9860d44fc300dc3a257a0f394cc8a",
"s": "0x509f817bdcf481fecb526fe686e627287cc9860d44fc300dc3a257a0f394cc8a",
"standardV": "0x0",
"to": "0xd14cedc448bfcd8cc3e1b94786573bd6fbd5c661",
"transactionIndex": "0x0",
"v": "0x77",
"value": "0x38d7ea4c68000"
}
}
# 调用注册比原地址合约
注册比原地址合约为Register
,继承了Pausable
和Ownable
,拥有暂停调用和权限控制功能。该合约对外提供了3个函数接口:
- addUser 该函数是供用户注册以太坊地址和比原地址的映射关系
- OwnerChangeRegistry 该函数供合约拥有者修改注册信息
- getVapor 该函数用于查询以太坊地址对应的比原地址
注册比原地址合约源代码如下:
pragma solidity ^0.4.16;
contract Ownable {
address public owner;
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
owner = msg.sender;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
if (newOwner != address(0)) {
owner = newOwner;
}
}
}
contract Pausable is Ownable {
bool public paused = false;
event Pause();
event Unpause();
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*/
modifier whenNotPaused() {
require(!paused);
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*/
modifier whenPaused() {
require(paused);
_;
}
/**
* @dev called by the owner to pause, triggers stopped state
*/
function pause() onlyOwner whenNotPaused public {
paused = true;
Pause();
}
/**
* @dev called by the owner to unpause, returns to normal state
*/
function unpause() onlyOwner whenPaused public {
paused = false;
Unpause();
}
}
contract Register is Pausable {
// eth 地址 ==> vapor 地址的 map
mapping(address => string) public registry;
// map 中添加新用户, eth 地址为合约调用者,仅未暂停状态下可以调用
function addUser(string vaporAddress) public whenNotPaused {
registry[msg.sender] = vaporAddress;
}
// 合约所有者可以任意更改 map 中的对应关系,仅合约所有者可以调用
function OwnerChangeRegistry(address ethAddress,string vaporAddress) public onlyOwner {
registry[ethAddress] = vaporAddress;
}
//返回 map 中eth 地址对应的 vapor 地址
function getVapor(address ethAddress) public constant returns (string) {
return registry[ethAddress];
}
}
官方开发了一个基于H5开发的以太坊注册比原合约地址的DAPP系统,如果钱包支持H5的嵌入,便可以直接使用(例如imtoken)。此外,钱包还可以根据自己的需求定制该合约的DAPP。