``` {.yaml} type: google.api.Service config_version: 3 http: rules: - selector: bdware.bdledger.api.Node.ClientVersion get: /v0/node/version - selector: bdware.bdledger.api.Ledger.CreateLedger post: /v0/ledgers body: "*" - selector: bdware.bdledger.api.Ledger.GetLedgers get: /v0/ledgers - selector: bdware.bdledger.api.Ledger.SendTransaction post: /v0/ledgers/{ledger}/transactions body: "*" - selector: bdware.bdledger.api.Query.GetBlockByHash get: /v0/ledgers/{ledger}/block - selector: bdware.bdledger.api.Query.GetBlocks post: /v0/ledgers/{ledger}/blocks/query body: "*" - selector: bdware.bdledger.api.Query.CountBlocks post: /v0/ledgers/{ledger}/blocks/count body: "*" - selector: bdware.bdledger.api.Query.GetRecentBlocks get: /v0/ledgers/{ledger}/blocks/recent - selector: bdware.bdledger.api.Query.GetTransactionByHash get: /v0/ledgers/{ledger}/transaction - selector: bdware.bdledger.api.Query.GetTransactionByBlockHashAndIndex get: /v0/ledgers/{ledger}/block/transaction - selector: bdware.bdledger.api.Query.GetTransactions post: /v0/ledgers/{ledger}/transactions/query body: "*" - selector: bdware.bdledger.api.Query.CountTransactions post: /v0/ledgers/{ledger}/transactions/count body: "*" ``` > **Note** > > Request/Response data of **bytes** type should/will be encoded with > [Base64](https://tools.ietf.org/html/rfc4648#section-4). > **Note** > > When using hash strings in URL, they need to be encoded with > [encodeURIComponent](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent). Request Examples {#_request_examples} ================ Node.ClientVersion {#_node_clientversion} ------------------ Get BDLedger node version GET http://{{IP}}:{{PORT}}/v0/node/version **Response.** ``` {.json} { "version": "dev-210119.a88bf4eb" } ``` Ledger.CreateLedger {#_ledger_createledger} ------------------- Create a new ledger POST http://{{IP}}:{{PORT}}/v0/ledgers **Request body.** ``` {.json} { "name": "test" } ``` **Response.** ``` {.json} { "ok": true } ``` Ledger.GetLedgers {#_ledger_getledgers} ----------------- Get all ledgers GET http://{{IP}}:{{PORT}}/v0/ledgers **Response.** ``` {.json} { "ledgers": [ "default", "test" ] } ``` Ledger.SendTransaction {#_ledger_sendtransaction} ---------------------- Send a new transaction POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions **Request body.** ``` {.json} { "transaction": { "type": 0, "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", "nonce": 52, "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" } } ``` **Response.** ``` {.json} { "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" } ``` Query.GetBlockByHash {#_query_getblockbyhash} -------------------- Get a block identified by its hash GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block?hash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D **hash** has to be encoded with [encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) **Response.** ``` {.json} { "block": { "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", "creator": "", "nonce": "0", "parentHashes": [ "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", "rk0DWMaUpRG82yVX+cFhbfhPFdw=", "3XkwkuMBearq8uavN76Te7Zdpl8=" ], "witnesses": [], "timestamp": "1611038043", "size": "0", "transactionCount": 1, "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "transactions": [ { "blockHash": "", "blockTimestamp": "0", "index": 0, "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "type": "RECORD", "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", "nonce": "0", "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" } ], "transactionHashes": [ "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" ] } } ``` Query.GetBlocks {#_query_getblocks} --------------- Get blocks in a timestamp range POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/query ``` {.protobuf} enum IncludeTransactions { NONE = 0; // Don't include transaction data HASH = 1; // Include transactions hashes FULL = 2; // Include full transactions } ``` Requirement: asciimath:\[\"start\_timestamp\"⇐\"end\_timestamp\"\] If only **end\_timestamp** is not specified, or asciimath:\[\"end\_timestamp\"-\"start\_timestamp\"\>\"query.maxDuration\"\], then **end\_timestamp** will be set to asciimath:\[\"start\_timestamp\"+\"query.maxDuration\"\]. If only **start\_timestamp** is not specified, then **start\_timestamp** will be set to asciimath:\[\"end\_timestamp\"-\"query.maxDuration\"\]. In all cases, **start\_timestamp** will never be earlier than the genesis block's timestamp, and **end\_timestamp** will never be later than the current timestamp when the node process the query request. **Request body 1.** ``` {.json} { "start_timestamp": 1611038000, "end_timestamp": 1611039000, "include_transactions": 0 } ``` **Response 1.** ``` {.json} { "blocks": [ { "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", "creator": "", "nonce": "0", "parentHashes": [ "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", "rk0DWMaUpRG82yVX+cFhbfhPFdw=", "3XkwkuMBearq8uavN76Te7Zdpl8=" ], "witnesses": [], "timestamp": "1611038043", "size": "0", "transactionCount": 1, "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "transactions": [], "transactionHashes": [] } ], "startTimestamp": "1611038043", "endTimestamp": "1611038043" } ``` **Request body 2.** ``` {.json} { "start_timestamp": 1611038000, "end_timestamp": 1611039000, "include_transactions": 1 } ``` **Response 2.** ``` {.json} { "blocks": [ { "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", "creator": "", "nonce": "0", "parentHashes": [ "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", "rk0DWMaUpRG82yVX+cFhbfhPFdw=", "3XkwkuMBearq8uavN76Te7Zdpl8=" ], "witnesses": [], "timestamp": "1611038043", "size": "0", "transactionCount": 1, "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "transactions": [], "transactionHashes": [ "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" ] } ], "startTimestamp": "1611038043", "endTimestamp": "1611038043" } ``` **Request body 3.** ``` {.json} { "start_timestamp": 1611038000, "end_timestamp": 1611039000, "include_transactions": 2 } ``` **Response 3.** ``` {.json} { "blocks": [ { "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", "creator": "", "nonce": "0", "parentHashes": [ "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", "rk0DWMaUpRG82yVX+cFhbfhPFdw=", "3XkwkuMBearq8uavN76Te7Zdpl8=" ], "witnesses": [], "timestamp": "1611038043", "size": "0", "transactionCount": 1, "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "transactions": [ { "blockHash": "", "blockTimestamp": "0", "index": 0, "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "type": "RECORD", "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", "nonce": "0", "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" } ], "transactionHashes": [ "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" ] } ], "startTimestamp": "1611038043", "endTimestamp": "1611038043" } ``` Query.CountBlocks {#_query_countblocks} ----------------- Count all blocks in a ledger, or blocks in a timestamp range POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/count Requirement: asciimath:\[\"start\_timestamp\"⇐\"end\_timestamp\"\] If neither **start\_timestamp** nor **end\_timestamp** is specified, then count all blocks in the specified ledger. If only **end\_timestamp** is not specified, then count all blocks with timestamps later than **start\_timestamp**. If only **start\_timestamp** is not specified, then count all blocks with timestamps earlier than **end\_timestamp**. In all cases, **start\_timestamp** will never be earlier than the genesis block's timestamp, and **end\_timestamp** will never be later than the current timestamp when the node process the query request. **Request body 1.** ``` {.json} {} ``` **Response 1.** ``` {.json} { "count": "5", "startTimestamp": "0", "endTimestamp": "1611039957" } ``` **Request body 2.** ``` {.json} { "start_timestamp": 1611038000, "end_timestamp": 1611039000 } ``` **Response 2.** ``` {.json} { "count": "1", "startTimestamp": "1611038000", "endTimestamp": "1611039000" } ``` Query.GetRecentBlocks {#_query_getrecentblocks} --------------------- Get recent **count** blocks (Only support IncludeTransactions=NONE for now) GET http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/recent?count=2 **Response.** ``` {.json} { "blocks": [ { "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", "creator": "", "nonce": "0", "parentHashes": [ "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", "rk0DWMaUpRG82yVX+cFhbfhPFdw=", "3XkwkuMBearq8uavN76Te7Zdpl8=" ], "witnesses": [], "timestamp": "1611038043", "size": "0", "transactionCount": 1, "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "transactions": [], "transactionHashes": [] }, { "hash": "rk0DWMaUpRG82yVX+cFhbfhPFdw=", "creator": "", "nonce": "0", "parentHashes": [ "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", "3XkwkuMBearq8uavN76Te7Zdpl8=", "8pZPR74OALIbps5XFb4dL/s0j0M=" ], "witnesses": [], "timestamp": "1610968019", "size": "0", "transactionCount": 1, "transactionsRoot": "LuxttCm/pSHVMOKF0sJExk+DJXc=", "transactions": [], "transactionHashes": [] } ], "startTimestamp": "1610968019", "endTimestamp": "1611038043" } ``` Query.GetTransactionByHash {#_query_gettransactionbyhash} -------------------------- Get a transaction identified by its hash GET http://{{IP}}:{{PORT}}/v0/ledgers/test/transaction?hash=VQBeA5Ee0Y5hqEileoQuYMHbOSE%3D **hash** has to be encoded with [encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) **Response.** ``` {.json} { "transaction": { "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", "blockTimestamp": "1611038043", "index": 0, "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "type": "RECORD", "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", "nonce": "0", "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" } } ``` Query.GetTransactionByBlockHashAndIndex {#_query_gettransactionbyblockhashandindex} --------------------------------------- Get a transaction identified by hash of the block it belongs to and its index inside the block GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block/transaction?blockHash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D&index=0 **blockHash** has to be encoded with [encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) **Response.** ``` {.json} { "transaction": { "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", "blockTimestamp": "1611038043", "index": 0, "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "type": "RECORD", "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", "nonce": "0", "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" } } ``` Query.GetTransactions {#_query_gettransactions} --------------------- Get transactions in a timestamp range POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/query **start\_timestamp** and **end\_timestamp** follow the same requirements and rules as in [???](#Query.GetBlocks). **Request body.** ``` {.json} { "start_timestamp": 1611038000, "end_timestamp": 1611039000 } ``` **Response.** ``` {.json} { "transactions": [ { "blockHash": "", "blockTimestamp": "0", "index": 0, "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", "type": "RECORD", "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", "nonce": "0", "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" } ], "startTimestamp": "1611038043", "endTimestamp": "1611038043" } ``` Query.CountTransactions {#_query_counttransactions} ----------------------- Count all transactions in a ledger, or transactions in a timestamp range POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/count **start\_timestamp** and **end\_timestamp** follow the same requirements and rules as in [???](#Query.CountBlocks). **Request body 1.** ``` {.json} {} ``` **Response 1.** ``` {.json} { "count": "4", "startTimestamp": "0", "endTimestamp": "1611039957" } ``` **Request body 2.** ``` {.json} { "start_timestamp": 1611038000, "end_timestamp": 1611039000 } ``` **Response 2.** ``` {.json} { "count": "1", "startTimestamp": "1611038000", "endTimestamp": "1611039000" } ```