XRP对接文档

XRP对接文档

技术预研

参考文档

  • 官方文档: https://xrpl.org/list-xrp-in-your-exchange.html

  • 官方文档: https://xrpl.org/list-xrp-as-an-exchange.html#flow-of-funds

  • 交易所对接XRP(内容齐全, 很推荐) https://blog.csdn.net/weixin_40396076/article/details/100202076

  • XRP瑞波币JAVA接入 https://blog.csdn.net/liu1765686161/article/details/82492937

  • XRP离线签名JAVA https://blog.csdn.net/liu1765686161/article/details/83347534

OperatorNetworkJSON-RPC URLWebSocket URLNotes
RippleMainnethttps://s1.ripple.com:51234/wss://s1.ripple.com/General purpose server cluster
RippleMainnethttps://s2.ripple.com:51234/wss://s2.ripple.com/Full-history server cluster
RippleTestnethttps://s.altnet.rippletest.net:51234/wss://s.altnet.rippletest.net/Testnet public server
RippleDevnethttps://s.devnet.rippletest.net:51234/wss://s.devnet.rippletest.net/Devnet public server
  • 获取历史数据(账户历史交易等):

    https://data.ripple.com

    https://testnet.data.api.ripple.com

几个关键的问题

1.用户充币地址如何离线生成?

交易所使用一个地址即可, 用户充币时需要填写 tag, 交易所通过tag区分用户的充值.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果用户不填写标签, 不能区分是哪个用户的充币, 只能人工干预.

ripple提供了一个接口, 来设置账户的接收交易, 必须填写 DestinationTag, 如果不填写则直接拒绝.

https://xrpl.org/require-destination-tags.html

这样的确防止了用户充币不填写标签的情况, 但是是否存在其他问题?

2.交易所的全节点如何搭建?
  • 字节搭建一个节点, 用于交易的广播, 和其他操作
  • 也可以直接使用ripple官方的接口查询交易, 和广播交易
3.用户充币如何扫描检测? 需要注意哪些问题?

https://xrpl.org/list-xrp-as-an-exchange.html#deposit-xrp-into-exchange

  • 获取测试币
Address
rpxSrARAeTE2Y699CsY5PwVEJ5v21TDrLi
Secret
ssYt3QxVJtAqtw88REsc7S7X3mHrZ
Balance
1,000 XRP

---------------


Address
rBQUkC3iBBAXV7XT4DJeCPiMHQM6PVE555
Secret
snTru9VEkoQNwRoKTJzNDVg2TDgQk
Balance
1,000 XRP
  • 查询账户交易历史: https://github.com/ripple/rippled-historical-database#get-account-transaction-history

GET /v2/accounts/{address}/transactions

FieldValueDescription
startString - TimestampStart time of query range. The default is the earliest date available. 开始时间戳
endString - TimestampEnd time of query range. The default is the current date. 结束时间戳
min_sequenceStringMinimum sequence number to query.
max_sequenceStringMax sequence number to query.
typeStringRestrict results to a specified transaction type. 交易类型, 普通的XRP转账类型是 Payment
resultStringRestrict results to a specified transaction result. 交易结果(成功还是失败), 成功: tesSUCCESS , 其他情况有不同的字符串状态
binaryBooleanReturn results in binary format. 是否返回十六进制字符串, 默认是false
descendingBooleanIf true, return results in reverse chronological order. The default is false. 按照时间降序排列, 默认是 false
limitIntegerMaximum results per page. The default is 20. Cannot be more than 1,000. 每页的交易数量
markerStringPagination key from previously returned response. 分页标志, 请求第二页以后的页需要带上此字段

例如:

https://data.ripple.com/v2/accounts/r3Vh1bZbktiWRyJBe6BB9H3okW577u37BE/transactions?limit=2&start=1564642511&end=1565101720
  
  
  {
        "result": "success",
        "count": 2,
        "transactions": [
            {
                "hash": "37554EEC36B8E76593387380752994E5017843000EA401BEEDAABD2294F0899F",
                "ledger_index": 49050181,
                "date": "2019-08-01T14:55:11+00:00",
                "tx": {
                    "TransactionType": "Payment",
                    "Flags": 2147483648,
                    "Sequence": 238920,
                    "Amount": "99900000",
                    "Fee": "1000",
                    "SigningPubKey": "02820C6D08111F0AE73F1ED0463C5B50D0E45BF3DB4A36B1FCF5B2C8FBD9BB3EE6",
                    "TxnSignature": "304402206ACF8B1C44098C6B3AE9F1266DDDC3D1EF18438849BCA6CA531B60617DBB9E660220092B01BBC60866ACC7713D5CA67618739FB04A0B35A5AB524887ECD54372F6A5",
                    "Account": "rfexLLNpC6dqyLagjV439EyvfqdYNHsWSH",
                    "Destination": "r3Vh1bZbktiWRyJBe6BB9H3okW577u37BE"
                },
                "meta": {
                    "TransactionIndex": 4,
                    "AffectedNodes": [
                        {
                            "CreatedNode": {
                                "LedgerEntryType": "AccountRoot",
                                "LedgerIndex": "5C0CAE11030D79C566101617FAEEA165B7D9A1342A2B4FD06309CA3578B65F4F",
                                "NewFields": {
                                    "Sequence": 1,
                                    "Balance": "99900000",
                                    "Account": "r3Vh1bZbktiWRyJBe6BB9H3okW577u37BE"
                                }
                            }
                        },
                        {
                            "ModifiedNode": {
                                "LedgerEntryType": "AccountRoot",
                                "PreviousTxnLgrSeq": 49050173,
                                "PreviousTxnID": "077DAEBEE3031E5001DA890F442F5AAC944B0B26EDC0A5025848B42E099A851C",
                                "LedgerIndex": "74A1C26DB171CE0528DA9230BA0E567BB6023FD07C6544BAC97E953605760CB8",
                                "PreviousFields": {
                                    "Sequence": 238920,
                                    "Balance": "1671679385"
                                },
                                "FinalFields": {
                                    "Flags": 131072,
                                    "Sequence": 238921,
                                    "OwnerCount": 0,
                                    "Balance": "1571778385",
                                    "Account": "rfexLLNpC6dqyLagjV439EyvfqdYNHsWSH"
                                }
                            }
                        }
                    ],
                    "TransactionResult": "tesSUCCESS",
                    "delivered_amount": "99900000"
                }
            },
            {
                "hash": "1535E53D3C74A3F03A325BE43BE134367FCDC425015E8CEA706767186672A65C",
                "ledger_index": 49160675,
                "date": "2019-08-06T14:28:40+00:00",
                "tx": {
                    "TransactionType": "Payment",
                    "Flags": 2147483648,
                    "SourceTag": 102889,
                    "Sequence": 1,
                    "DestinationTag": 102889,
                    "Amount": "75000000",
                    "Fee": "5000",
                    "SigningPubKey": "02ED0A3DC98978AE75835F403B5BC79A994DBD41874A8A6BD2498E8FC1AD48BDF4",
                    "TxnSignature": "304402206DCF74EBF05C15D5F6ECB5CF18DB02E62D0C003C48D087E9BF18D8AB0269AF7502205080B6D155F95AB021A575277CD089898688C221F178826105C757FC48D771BA",
                    "Account": "r3Vh1bZbktiWRyJBe6BB9H3okW577u37BE",
                    "Destination": "rardRtq3DWjqgxLpEoHPcFv7dSuv4FgbSN"
                },
                "meta": {
                    "TransactionIndex": 4,
                    "AffectedNodes": [
                        {
                            "ModifiedNode": {
                                "LedgerEntryType": "AccountRoot",
                                "PreviousTxnLgrSeq": 49050181,
                                "PreviousTxnID": "37554EEC36B8E76593387380752994E5017843000EA401BEEDAABD2294F0899F",
                                "LedgerIndex": "5C0CAE11030D79C566101617FAEEA165B7D9A1342A2B4FD06309CA3578B65F4F",
                                "PreviousFields": {
                                    "Sequence": 1,
                                    "Balance": "99900000"
                                },
                                "FinalFields": {
                                    "Flags": 0,
                                    "Sequence": 2,
                                    "OwnerCount": 0,
                                    "Balance": "24895000",
                                    "Account": "r3Vh1bZbktiWRyJBe6BB9H3okW577u37BE"
                                }
                            }
                        },
                        {
                            "ModifiedNode": {
                                "LedgerEntryType": "AccountRoot",
                                "PreviousTxnLgrSeq": 49158980,
                                "PreviousTxnID": "490ACD5C7B198581EDB1384FB58EBEEA5CF41E309C569E1E7EAEB7EFA7741F81",
                                "LedgerIndex": "9DDD6B3B7E3902EE1B3D27461CD2DB73AFC5A6C0F292DED496AD6B403BFE376A",
                                "PreviousFields": {
                                    "Balance": "20000000"
                                },
                                "FinalFields": {
                                    "Flags": 131072,
                                    "Sequence": 360,
                                    "OwnerCount": 0,
                                    "Balance": "95000000",
                                    "Account": "rardRtq3DWjqgxLpEoHPcFv7dSuv4FgbSN"
                                }
                            }
                        }
                    ],
                    "TransactionResult": "tesSUCCESS",
                    "delivered_amount": "75000000"
                }
            }
        ]
    }
  
4.如何转账(离线签名)?
  • 获取余额 GET /v2/accounts/{address}/balances

  • 手续费 : /v2/network/fees?interval=day&limit=3&descending=true

  • 获取账户信息(Sequence)

  
   //请求
  {
      "method": "account_info",
      "params": [
          {
              "account": "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
              "strict": true,
              "ledger_index": "current",
              "queue": true
          }
      ]
  }

  //返回
  {
      "result": {
          "account_data": {
              "Account": "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
              "Balance": "362981155",
              "Flags": 1179648,
              "LedgerEntryType": "AccountRoot",
              "OwnerCount": 0,
              "PreviousTxnID": "A9F85C8B6578F543034DB03EBBEA05D814D5AD0BEEFC7173B0F774F022AC273C",
              "PreviousTxnLgrSeq": 2360169,
              "RegularKey": "rJ6pSBmfPHFjsd6aog3Qz8f8tGC7XLDKE1",
              "Sequence": 219,
              "index": "92FA6A9FC8EA6018D5D16532D7795C91BFB0831355BDFDA177E86C8BF997985F"
          },
          "ledger_current_index": 2742581,
          "queue_data": {
              "txn_count": 0
          },
          "status": "success",
          "validated": false
      }
  }

  • 交易广播
POST    https://s.altnet.rippletest.net:51234

  

//请求
  {
      "method": "submit",
      "params": [
          {
              "tx_blob": "1200002280000000240000000861400000000000000568400000000000000C7321028DEF81438DCDE390BE352C8BAA877CED55BBB193FE10E4C713D4CBF7E6DDA02E74473045022100B1F8F907F6576B8EB11E8691FCE29557D09D62D703DA2891381B38AA72D09251022063C2613D63535F89E2A36A0F3F3C7C27D263B494CFBD4891910F7AF94F8A3F0381141573E2D9EC61FBB6DFB2C5D64C111E9AEEF6F91083147214A2B8C4F87C65102156B3FE3EEC0B1DB23482"
          }
      ]
  }

  

  //返回

  {
      "result": {
          "engine_result": "tesSUCCESS",
          "engine_result_code": 0,
          "engine_result_message": "The transaction was applied. Only final in a validated ledger.",
          "status": "success",
          "tx_blob": "1200002280000000240000000861400000000000000568400000000000000C7321028DEF81438DCDE390BE352C8BAA877CED55BBB193FE10E4C713D4CBF7E6DDA02E74473045022100B1F8F907F6576B8EB11E8691FCE29557D09D62D703DA2891381B38AA72D09251022063C2613D63535F89E2A36A0F3F3C7C27D263B494CFBD4891910F7AF94F8A3F0381141573E2D9EC61FBB6DFB2C5D64C111E9AEEF6F91083147214A2B8C4F87C65102156B3FE3EEC0B1DB23482",
          "tx_json": {
              "Account": "rpxSrARAeTE2Y699CsY5PwVEJ5v21TDrLi",
              "Amount": "5",
              "Destination": "rBQUkC3iBBAXV7XT4DJeCPiMHQM6PVE555",
              "Fee": "12",
              "Flags": 2147483648,
              "Sequence": 8,
              "SigningPubKey": "028DEF81438DCDE390BE352C8BAA877CED55BBB193FE10E4C713D4CBF7E6DDA02E",
              "TransactionType": "Payment",
              "TxnSignature": "3045022100B1F8F907F6576B8EB11E8691FCE29557D09D62D703DA2891381B38AA72D09251022063C2613D63535F89E2A36A0F3F3C7C27D263B494CFBD4891910F7AF94F8A3F03",
              "hash": "90C4B383D76861E317449DD0D6018F340AD9D6B4C05222983791569AE1F771E3"
          }
      }
  }

  • XRP的Sequence机制

    XRP的sequence机制和ETH的sequence不同, XRP的sequence不支持大于当前sequence的交易, 如果使用大于当前的sequence的值构造交易, 那么就会出现 terPRE_SEQ的错误, 如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

离线签名方案

方案1: 导出 rippled中的签名相关的函数(主要是序列化相关的)

此方案非常繁琐

rippled 源码支持 x64, 与我在项目中使用的 x86 不相符, 就算导出成功 , 也需要解决兼容问题

方案2: 将序列化的工作交易python服务端

此方案应作为首选方案

离线签名只负责签名序列化后的交易, 广播的时候再由Python服务端进行内容的进一步组装和序列化.

方案3: 自己针对 Payment交易类型, 实现序列化库

此方案难度不大

可以参考 rippled 或 ripple-lib 或 ripple-lib-python 实现一个简单的序列化库(仅针对 Payment交易类型)

方案4 : 使用 rippled自带的 sign 接口

此方案是最简单的.

直接使用 rippled的自带签名接口, 当然需要编译 rippled.exe(windows编译比较麻烦, 按照官方的文档可以编译成功), 如果是linux 直接安装即可

配置 rippled的配置文件rippled.cfg, 设置 signing_supporttrue就可以支持 signsign_for

[signing_support]
true

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在cmd中启动

rippled.exe  --net --silent --conf ./rippled.cfg

请求例子

POST  https://192.168.10.114:5005

{
    "method": "sign",
    "params": [{
        "secret": "ssYt3QxVJtAqtw88REsc7S7X3mHrZ",
        "offline":true,
        "tx_json": {
            "TransactionType": "Payment",
            "Account": "rpxSrARAeTE2Y699CsY5PwVEJ5v21TDrLi",
            "Destination": "rBQUkC3iBBAXV7XT4DJeCPiMHQM6PVE555",
            "Amount": "5100000",
            "Sequence": 10,
            "SigningPubKey": "",
            "Fee": "12"
        }
    }]
}



//curl 测试

[root@demo ~]# 
[root@demo ~]# curl -H "Content-Type: application/json" -X POST  --data '{"method": "sign","params": [{"secret":"ssYt3QxVJtAqtw88REsc7S7X3mHrZ","offline":true,"tx_json":{"TransactionType":"Payment","Account":"rpxSrARAeTE2Y699CsY5PwVEJ5v21TDrLi","Destination":"rBQUkC3iBBAXV7XT4DJeCPiMHQM6PVE555","Amount":"5100000","Sequence":10,"SigningPubKey":"","Fee":"12"}}]}' http://127.0.0.1:5005
{"result":{"deprecated":"This command has been deprecated and will be removed in a future version of the server. Please migrate to a standalone signing tool.","status":"success","tx_blob":"1200002280000000240000000A6140000000004DD1E068400000000000000C7321028DEF81438DCDE390BE352C8BAA877CED55BBB193FE10E4C713D4CBF7E6DDA02E74473045022100F5EF279E894462443A67A44134789FAA56F3DEF1EF0F4E582B6703FF4612990502200257E31D7A5A102B2BD363E819B199B5B09CD32BCEF4552EB3C8E4DBB3ABC7AA81141573E2D9EC61FBB6DFB2C5D64C111E9AEEF6F91083147214A2B8C4F87C65102156B3FE3EEC0B1DB23482","tx_json":{"Account":"rpxSrARAeTE2Y699CsY5PwVEJ5v21TDrLi","Amount":"5100000","Destination":"rBQUkC3iBBAXV7XT4DJeCPiMHQM6PVE555","Fee":"12","Flags":2147483648,"Sequence":10,"SigningPubKey":"028DEF81438DCDE390BE352C8BAA877CED55BBB193FE10E4C713D4CBF7E6DDA02E","TransactionType":"Payment","TxnSignature":"3045022100F5EF279E894462443A67A44134789FAA56F3DEF1EF0F4E582B6703FF4612990502200257E31D7A5A102B2BD363E819B199B5B09CD32BCEF4552EB3C8E4DBB3ABC7AA","hash":"107120D4E131189A4BCF8D771CDB308A64FF5EED5B805C106F3CA41089CD06AC"}}}

[root@demo ~]# 

完整的配置文件

  • rippled.cfg
[server]
port_rpc_admin_local
port_peer
port_ws_admin_local
#port_ws_public
#ssl_key = /etc/ssl/private/server.key
#ssl_cert = /etc/ssl/certs/server.crt

[port_rpc_admin_local]
port = 5005
#ip = 127.0.0.1
ip=0.0.0.0
admin = 127.0.0.1
protocol = http

[port_peer]
port = 51235
ip = 0.0.0.0
# alternatively, to accept connections on IPv4 + IPv6, use:
#ip = ::
protocol = peer

[port_ws_admin_local]
port = 6006
ip = 127.0.0.1
admin = 127.0.0.1
protocol = ws

#[port_ws_public]
#port = 6005
#ip = 127.0.0.1
#protocol = wss

#-------------------------------------------------------------------------------

[node_size]
tiny
#medium

# This is primary persistent datastore for rippled.  This includes transaction
# metadata, account states, and ledger headers.  Helpful information can be
# found here: https://ripple.com/wiki/NodeBackEnd
# delete old ledgers while maintaining at least 2000. Do not require an
# external administrative command to initiate deletion.
[node_db]
type=RocksDB
path=./db/rocksdb
open_files=2000
filter_bits=12
cache_mb=256
file_size_mb=8
file_size_mult=2
online_delete=2000
advisory_delete=0

# This is the persistent datastore for shards. It is important for the health
# of the ripple network that rippled operators shard as much as practical.
# NuDB requires SSD storage. Helpful information can be found here
# https://ripple.com/build/history-sharding
#[shard_db]
#path=/var/lib/rippled/db/shards/nudb
#max_size_gb=500

[database_path]
./db

# This needs to be an absolute directory reference, not a relative one.
# Modify this value as required.
[debug_logfile]
./debug.log

[sntp_servers]
time.windows.com
time.apple.com
time.nist.gov
pool.ntp.org

# To use the XRP test network (see https://ripple.com/build/xrp-test-net/),
# use the following [ips] section:
# [ips]
# r.altnet.rippletest.net 51235

# File containing trusted validator keys or validator list publishers.
# Unless an absolute path is specified, it will be considered relative to the
# folder in which the rippled.cfg file is located.
[validators_file]
validators.txt

# Turn down default logging to save disk space in the long run.
# Valid values here are trace, debug, info, warning, error, and fatal
[rpc_startup]
{ "command": "log_level", "severity": "warning" }

# If ssl_verify is 1, certificates will be validated.
# To allow the use of self-signed certificates for development or internal use,
# set to ssl_verify to 0.
[ssl_verify]
0

[signing_support]
true


[peer_private]
1

[peers_max]
0

[overlay]
ip_limit = 0


[fetch_depth]
0



  • validators.txt 默认的即可
#

# Default validators.txt
#
# A list of domains to bootstrap a nodes UNLs or for clients to indirectly
# locate IPs to contact the Ripple network.
#
# This file is UTF-8 with Dos, UNIX, or Mac style end of lines.
# Blank lines and lines starting with a '#' are ignored.
# All other lines should be hankos or domain names.
#
#
#
# [validators]
#
#   List of the validation public keys of nodes to always accept as validators.
#
#   Manually listing validator keys is not recommended for production networks.
#   See validator_list_sites and validator_list_keys below.
#
#   Examples:
#    n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
#    n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt
#
# [validator_list_sites]
#
#   List of URIs serving lists of recommended validators.
#
#   The latest list of recommended validator sites can be
#   obtained from https://ripple.com/ripple.txt
#
#   Examples:
#    https://vl.ripple.com
#    http://127.0.0.1:8000
#    file:///etc/opt/ripple/vl.txt
#
# [validator_list_keys]
#
#   List of keys belonging to trusted validator list publishers.
#   Validator lists fetched from configured sites will only be considered
#   if the list is accompanied by a valid signature from a trusted
#   publisher key.
#   Validator list keys should be hex-encoded.
#
#   The latest list of recommended validator keys can be
#   obtained from https://ripple.com/ripple.txt
#
#   Examples:
#    ed499d732bded01504a7407c224412ef550cc1ade638a4de4eb88af7c36cb8b282
#    0202d3f36a801349f3be534e3f64cfa77dede6e1b6310a0b48f40f20f955cec945
#    02dd8b7075f64d77d9d2bdb88da364f29fcd975f9ea6f21894abcc7564efda8054
#

# The default validator list publishers that the rippled instance
# trusts.
#
# WARNING: Changing these values can cause your rippled instance to see a
#          validated ledger that contradicts other rippled instances'
#          validated ledgers (aka a ledger fork) if your validator list(s)
#          do not sufficiently overlap with the list(s) used by others.
#          See: https://arxiv.org/pdf/1802.07242.pdf

[validator_list_sites]
https://vl.ripple.com

[validator_list_keys]
ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734

# To use the XRP test network (see https://ripple.com/build/xrp-test-net/),
# use the following configuration instead:
#
# [validator_list_sites]
# https://vl.altnet.rippletest.net
#
# [validator_list_keys]
# ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值