-
Notifications
You must be signed in to change notification settings - Fork 45
交易所对接指南(中文)
这篇文档主要描述了交易所如何一步一步完成和V Systems (VSYS)区块链的对接交互。
For English version Instructions for Exchanges, please click here
目前阶段,标准硬件配置是2核CPU,16G内存,和512GB高速硬盘的独立主机。
推荐配置是i3 large型号的亚马逊云主机(AWS)
可以是所有 Java 1.8 和 Python 可以运行的任何操作系统 (包括 Ubuntu, CentOS, MacOS, Windows 等)。
我们推荐的操作系统是 Ubuntu 16.04 LTS (或其更高版本)。
这篇文档我们以Ubuntu 16.04为例进行介绍。
首先我们更新软件包管理器
$ sudo apt-get update在主机上安装Java 1.8
$ sudo apt-get install openjdk-8-jdk检查Java版本(需要删除低版本的Java)
$ java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-0ubuntu0.16.04.1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)如果您选择编译我们的源码搭建全节点,需要安装Scala编译工具(SBT)
$ echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823
$ sudo apt-get update
$ sudo apt-get install sbt如果没有Unzip和Git,请在主机上安装这些软件
$ sudo apt-get install unzip
$ sudo apt-get install git-core有两种方法准备全节点程序,请任意选择一个方法。
从GitHub上下载源代码
$ git clone https://github.com/virtualeconomy/v-systems.git
$ cd vsys用SBT编译源代码。如果您希望编译测试网(Testnet)的V全节点,请运行
# Compile TestNet V full node
$ sbt -Dnetwork=testnet packageAll如果您希望编译主网(Mainnet)的V全节点,请运行
# Compile MainNet V full node
$ sbt packageAll编译好的文件将会放在target/vsys-all-[version].jar这个位置。复制到你自己的工作目录,例如:
$ mkdir ../vsys-node
$ cp target/vsys-all-*.jar ../vsys-node/v-systems.jar
$ cd ../vsys-node如果您不想编译源代码,您也可以选择在 https://github.com/virtualeconomy/v-systems/releases 下载最新的JAR文件。
将v-systems-[version].jar保存到您的工作目录。
设置您的配置文件
# V Systems node settings
vsys {
# Path Settings
directory = <block data folder path>
# Application logging level. Could be DEBUG | INFO | WARN | ERROR. Default value is INFO.
logging-level = INFO
# P2P Network settings
network {
known-peers = ["<peer ip>:<peer port>"]
black-list-residence-time = 30s
peers-broadcast-interval = 5s
connection-timeout = 30s
# Network address to bind to
bind-address = "0.0.0.0"
# Node name to send during handshake. Comment this string out to set random node name.
# node-name = "My MAINNET node"
# String with IP address and port to send as external address during handshake. Could be set automatically if uPnP is enabled.
declared-address = "localhost:9921"
}
# Wallet settings
wallet {
# Password to protect wallet file
password = ""
# Wallet seed as BASE58 string
# seed = ""
}
# Blockchain settings
blockchain.type = TESTNET # Should be TESTNET or MAINNET
# Matcher settings
matcher.enable = no
# Minter settings
miner {
enable = yes
offline = no
quorum = 1
generation-delay = 1s
interval-after-last-block-then-generation-is-allowed = 120h
tf-like-scheduling = no
# Left to empty as default to minter address
reward-address = ""
}
# Node's REST API settings
rest-api {
# Enable/disable node's REST API
enable = yes
# Network address to bind to
bind-address = "0.0.0.0"
# Hash of API key string
api-key-hash = "Fo8fR7J1gB3k2WoaE6gYKMwgWfoh9EtZtXAMBxYYCJWG"
}
checkpoints.public-key = "A9MX22tXpNdTTx5wBf3CunZz299c1nnca6kH3MzL312L"
}
-
directory应该设为您自己的工作目录。我们建您挂载一个较大的硬盘,然后工作目录设置到这个硬盘下。
-
known-peers 这项最好填3个或以上的已知节点。您可以在V explorer查询这些已知节点。现在正在运行的一些节点有:
# 测试网 known-peers = ["18.179.34.202:9923", "13.250.53.12:9923", "18.188.219.229:9923"] # 主网 (欲知更多节点请和我们联系) known-peers = ["13.55.174.115:9921","52.30.23.41:9921","13.113.98.91:9921","3.121.94.10:9921", "54.147.255.148:9921"] -
blockchain.type 应该填 TESTNET 或 MAINNET.
-
为安全起见,api-key-hash这项最好设置成您自己的哈希值。您可以通过这个命令算出您的api密钥的哈希值:
curl -X POST -d '<输入任意字符作为您的api密钥>' 'https://test.v.systems/api/utils/hash/secure' -
最后,我们命名并保存配置文件,例如命名为"vsys.conf"。
我们建立一个screen并运行
$ screen -S vsys-node
$ sudo java -jar v-systems*.jar vsys.conf如果需要退出screen,可以在键盘上按 Ctrl + A + D。
如果需要再次进入screen看状态,可以运行
$ screen -x vsys-node安全提醒:所有的全节点都提供RESTful API进行交互,RESTful API会用到9922端口。安全起见,我们建议交易所修改防火墙规则,不要将9922端口开放到公网,仅内网使用。
以下是调用API的几种方法。
如果您使用python对接,我们强烈建议您使用pyvsystems项目完成交互对接。详情请参阅这里。
您可以打开浏览器输入http://<全节点ip>:9922使用Swagger,在这里也可以查阅所有可以使用的API。
如果没有安装curl,请安装这个程序,用于发送HTTP请求。
$ sudo apt-get install curl您可以用以下方法测试连接
$ curl -X GET --header 'Accept: application/json' 'http://<节点ip>:9922/blocks/height'如果请求成功,您将收到类似这样的回应:
{
"height": 2400326
}
发送HTTP POST请求调用/addresses这个API
$ curl -X POST --header 'Accept: application/json' --header 'api_key: <节点api密钥>' 'http://<节点 ip>:9922/addresses'如果创建成功,您将会收到一个包含钱包地址的回应:
{
"address": "AUBBmrf5cuBf9XrSaX98mxWmcNBwULqQhQK"
}
创建的钱包数据都会保存在<block data folder path>/wallet/wallet.dat这个文件里,这个文件最好定期进行备份。
我们也可以根据seed还原钱包,如果查找钱包的seed,可以通过发送HTTP GET调用/addresses/seed/{address} 这个API找到seed(需要带入API密钥),例如
$ curl -X GET --header 'Accept: application/json' --header 'api_key: <节点api密钥>' 'http://<节点ip>:9922/addresses/seed/AU9KCwJm6mG9YxSb3LdjVi6LDwRGey1knfy'如果成功将返回类似这样的结果:
{
"address": "AU9KCwJm6mG9YxSb3LdjVi6LDwRGey1knfy",
"seed": "GY7T8WpppuficZJs9CnEuntLkk4vXw7qkZ1SMtZ3qAas"
}
当您知道了seed,您可以通过 wallet-generator 这个项目来还原钱包地址。
使用 HTTP GET 调用 /addresses API 获取节点内的全部钱包:
$ curl -X GET 'http://<节点ip>:9922/addresses'如果成功将返回类似结果:
[
"ATy98tPdobDBKA35n5CJed6u3AmxKLT3TTV",
"ATys7iafCN4xHz9bJyKm4JNfKpk9f1uBBXT",
"AU1TFgjs3g1NMkXW5CGTGj96t8qijs6ScrP",
"ATubqbssJKtPfyebkmct4jv9YSue8xrhMLa",
"AU9KCwJm6mG9YxSb3LdjVi6LDwRGey1knfy",
"ATwMEAGfNhbRCRSApro8HWG2L65HMMa42KP",
"AU4rMtj3zEJesVQ94Az8ajncNMgtK6uzeHB",
"ATtdkLaHDPZQx3LsUfrKisRcrMkvfg18LGa",
"ATxa6h87rBrNYKDCkagageiPzTMFgcGmefA",
"AU8R9ri7eG968zuJuLQVLMiUzRNXvQwNPwE"
]
随着越来越多的钱包被创建,我们最好限制分批返回结果。我们可以通过 HTTP GET /addresses/seq/{from}/{to} 这个API拿到任意范围的钱包地址,例如
$ curl -X GET 'http://<节点ip>:9922/addresses/seq/5/10'如果成功将返回类似结果:
[
"ATwMEAGfNhbRCRSApro8HWG2L65HMMa42KP",
"AU4rMtj3zEJesVQ94Az8ajncNMgtK6uzeHB",
"ATtdkLaHDPZQx3LsUfrKisRcrMkvfg18LGa",
"ATxa6h87rBrNYKDCkagageiPzTMFgcGmefA",
"AU8R9ri7eG968zuJuLQVLMiUzRNXvQwNPwE"
]
查询余额可以通过 HTTP GET 调用 /addresses/balance/details/{address}
$ curl -X GET 'http://<节点ip>:9922/addresses/balance/details/AU8R9ri7eG968zuJuLQVLMiUzRNXvQwNPwE'如果成功将返回类似结果:
{
'address': 'AU8R9ri7eG968zuJuLQVLMiUzRNXvQwNPwE',
'regular': 109010000000, # regular balance
'available': 108910000000, # available balance (regular - leased out)
'effective': 108910000000, # effective balance (regular - leases out + leased in)
'mintingAverage': 108909964800, # for minter used
'height': 643936
}
返回中, available 的值是最终可用余额 (100000000 = 1 VSYS).
使用 HTTP POST 调用 /vsys/payment API
$ curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'api_key: <节点api密钥>' -d '{ \
"amount": 100000000, \
"fee": 10000000, \
"feeScale": 100, \
"sender": "ATtRykARbyJS1RwNsA6Rn1Um3S7FuVSovHK", \
"attachment": "", \
"recipient": "ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX" \
}' 'http://<节点ip>:9922/vsys/payment'在请求的JSON结构中,
amount 是支付给对方的费用,100000000 = 1 VSYS。
fee 是交易费,最小交易费10000000 (0.1 VSYS)。
feeScale 目前是固定值100。
sender 是支付方的钱包地址。
recipient 是接受方的钱包地址。
attachment 可以说任意字符(最多140个字符),用base58编码填入此项。
如果成功将返回类似结果:
{
"type": 2,
"id": "EoNQyNouEKg8pDcEEPY2dJL9FMQx61YFk1Sn5EJN8H7K",
"fee": 10000000,
"timestamp": 1544083814291691000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "3orvgyRKf45FRyiCkcA3CzAGDvyEpBpXZzYGEGZnpZK5",
"signature": "t1X2zmw5a2b9iaLgtsHyHKgEmKo6GCFuMFQsZNqj8ZkzpVbRKhWUttqUDfcjzcn5w7VgVVvf8cetr1mh2d2xypQ"
}
],
"recipient": "ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX",
"feeScale": 100,
"amount": 100000000,
"attachment": ""
}
用 HTTP GET 调用 /transactions/address/{address}/limit/{limit} API,例如,
$ curl -X GET 'http://<节点ip>:9922/transactions/address/ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX/limit/5'如果成功将返回类似结果:
[
[
{
"type": 2,
"id": "EoNQyNouEKg8pDcEEPY2dJL9FMQx61YFk1Sn5EJN8H7K",
"fee": 10000000,
"timestamp": 1544083814291691000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "3orvgyRKf45FRyiCkcA3CzAGDvyEpBpXZzYGEGZnpZK5",
"signature": "t1X2zmw5a2b9iaLgtsHyHKgEmKo6GCFuMFQsZNqj8ZkzpVbRKhWUttqUDfcjzcn5w7VgVVvf8cetr1mh2d2xypQ"
}
],
"recipient": "ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX",
"feeScale": 100,
"amount": 100000000,
"attachment": "",
"status": "Success",
"feeCharged": 10000000
},
{
"type": 4,
"id": "FiMiErppddPfFCmehu1ziKNTqyzBFsLRj6gh9y45JKKD",
"fee": 10000000,
"timestamp": 1543569020372515800,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "B2Khd89jtnpuzGdnyGRcnKycZMBCo6PsotFcWWi1wMDV",
"signature": "2hpsVXZVs2Wmg5ixD8PqvMJoC3CAqgTqvapYkuFAxbLvoyXRu45q9HXZQyqCzHeiHocGFM8phPkmDuM566Xu59em"
}
],
"feeScale": 100,
"leaseId": "D8mGb2YSGyKr5Q3WATnpQP8JvyDdteXwieo5khwsTEyY",
"status": "Success",
"feeCharged": 10000000,
"lease": {
"type": 3,
"id": "D8mGb2YSGyKr5Q3WATnpQP8JvyDdteXwieo5khwsTEyY",
"fee": 10000000,
"timestamp": 1543569009108564000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "B2Khd89jtnpuzGdnyGRcnKycZMBCo6PsotFcWWi1wMDV",
"signature": "8TDUgnkNbrPL6VMLFzDnhZvABfRqXitFX46mmvpohsdeRHKaNtWCs5C7m6avaUH2NjiFS7jGFov1CY5s3W8Zc5V"
}
],
"amount": 100000000,
"recipient": "AU6GsBinGPqW8zUuvmjgwpBNLfyyTU3p83Q",
"feeScale": 100
}
},
{
"type": 3,
"id": "D8mGb2YSGyKr5Q3WATnpQP8JvyDdteXwieo5khwsTEyY",
"fee": 10000000,
"timestamp": 1543569009108564000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "B2Khd89jtnpuzGdnyGRcnKycZMBCo6PsotFcWWi1wMDV",
"signature": "8TDUgnkNbrPL6VMLFzDnhZvABfRqXitFX46mmvpohsdeRHKaNtWCs5C7m6avaUH2NjiFS7jGFov1CY5s3W8Zc5V"
}
],
"amount": 100000000,
"recipient": "AU6GsBinGPqW8zUuvmjgwpBNLfyyTU3p83Q",
"feeScale": 100,
"status": "Success",
"feeCharged": 10000000
},
{
"type": 2,
"id": "He17g3JXtbXgMiWCTGwnNMPfvfFH5tvyJfYZ7BiWGBZK",
"fee": 10000000,
"timestamp": 1543568995612184000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "CbUPwcCJaMqYSjZGXy4LrkTfV2ncP27Chqyd2QKXfJxn",
"signature": "24fNpVr8qjrKuDNd8JSeZgkSa4BuS44kxupiAYPHxCbbPMBs2DyT7VDnqAWsJkYZxXWadqiQs7HFxW9uVULrGAtt"
}
],
"recipient": "ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX",
"feeScale": 100,
"amount": 100000000,
"attachment": "",
"status": "Success",
"feeCharged": 10000000
},
{
"type": 2,
"id": "2FVTJUpUJAhZJWkVYHHCG4nRXkYqwQcKsGEK8uwx3A58",
"fee": 10000000,
"timestamp": 1543568982176328000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "B2Khd89jtnpuzGdnyGRcnKycZMBCo6PsotFcWWi1wMDV",
"signature": "3DShPFQLidR1nbTKDrrhpp6SZdiL1hKtjYaGANzGuaWqjpGggPgtrCzw5XYXXktt2sFgWnmFVfTf4gNkmNPNyS2v"
}
],
"recipient": "AU6GsBinGPqW8zUuvmjgwpBNLfyyTU3p83Q",
"feeScale": 100,
"amount": 100000000,
"attachment": "",
"status": "Success",
"feeCharged": 10000000
}
]
]
几个常见的交易类型ID:
2 = 支付交易
3 = 租赁交易
4 = 取消租赁交易
5 = 挖矿交易
- wallet-generator (Scala)
- VSYS_HDkey_java (Java)
- VSYS_HDkey_go (Go)