FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME

Contenido

  1. Bytecoin Wallet Daemon JSON RPC API
  2. Bytecoin Node Daemon JSON RPC API
  3. Running Bytecoin Services
  4. Integration Guide
  5. Wallet File

Bytecoin Wallet Daemon JSON RPC API

## Introduction

The Bytecoin Wallet Daemon (`walletd`, Bytecoin RPC Wallet) is designed to manage a user's account while operating together with a [Bytecoin Node Daemon](Bytecoin-Node-Daemon-JSON-RPC-API). To start the `walletd` you must pass a path to a [wallet file](Wallet-File) as a command-line parameter which identifies the context the service will work within.

## Service Location

By default, the Bytecoin Wallet Daemon is only bound to `127.0.0.1` (`localhost`) interface, so it can only be reached from the same computer it runs on. To bind it to all interfaces, use `–walletd-bind-address=0.0.0.0:8070` command line argument (note that specifying port is mandatory).

To make a JSON PRC request to the `walletd` you should make an HTTP POST request to an entry point: ``` http:<ip>:<port>/json_rpc ``` where: * `<ip>` is the IPv4 address of the `walletd` service. If the service is on a local machine, use `127.0.0.1` instead of `localhost`. * `<port>` is TCP port of `walletd`. By default the service is bound to `8070`. ## Curl Template ``` curl -s -u <user>:<pass> -X POST http:<ip>:<port>/json_rpc -H 'Content-Type: application/json-rpc' -d '{“jsonrpc”: “2.0”, “id”: “<id>”, “method”: “<method>”, “params”: {<params>}}' ```

## Methods

### Address and key management

Method Description
———————————————————————————————————————————————-
[`create_addresses`](Bytecoin-Wallet-Daemon-JSON-RPC-API#1-create-addresses) Adds addresses into the wallet file.
[`get_addresses`](Bytecoin-Wallet-Daemon-JSON-RPC-API#2-get-addresses) Returns a list of addresses extracted from the wallet file.
[`get_view_key_pair`](Bytecoin-Wallet-Daemon-JSON-RPC-API#3-get-view-key-pair) Returns a view key pair shared by addresses.

### Balance and history of transfers

Method Description
—————————————————————————————————————————————————————-
[`get_status`](Bytecoin-Wallet-Daemon-JSON-RPC-API#6-get-status) Returns combined status of `walletd` and `bytecoind`.
[`get_balance`](Bytecoin-Wallet-Daemon-JSON-RPC-API#5-get-balance) Returns balance for a single address or all addresses.
[`get_unspents`](Bytecoin-Wallet-Daemon-JSON-RPC-API#9-get-unspents) Returns balance split into outputs.
[`get_transfers`](Bytecoin-Wallet-Daemon-JSON-RPC-API#8-get-transfers) Allows iterating through history of transfers to/from addresses.
[`create_send_proof`](Bytecoin-Wallet-Daemon-JSON-RPC-API#4-create-send-proof) Creates send-proof that money has been sent to an address.
[`check_send_proof`](Bytecoin-Wallet-Daemon-JSON-RPC-API#12-check-send-proof) Checks correctness of the given send-proof.
[`get_transaction`](Bytecoin-Wallet-Daemon-JSON-RPC-API#7-get-transaction) Returns transaction (only if it has transfer(s) to/from any address) by hash.

### Sending money

Method Description
———————————————————————————————————————————————————————————
[`create_transaction`](Bytecoin-Wallet-Daemon-JSON-RPC-API#10-create-transaction) Builds a transaction by specifying transfers you want to make and returns it for inspection.
[`send_transaction`](Bytecoin-Wallet-Daemon-JSON-RPC-API#11-send-transaction) Sends previously created transaction to the network.

### 1. Create Addresses

#### About

Either adds new or imports existing addresses (with corresponding spend keys) into a wallet file. To generate a new random key pair (and address, of course), you append an empty string to a `secret_spend_keys` array. To import an existing address, you append its secret spend key to a `secret_spend_keys` array. If you import existing addresses created some time ago, specify `creation_timestamp` so the `walletd` can rescan the blockchain starting from that point of time, looking for transactions to/from those addresses.

Adding an existing secret spend key is not an error, it will just return a corresponding address together with that key.

This method returns arrays of both addresses and secret spend keys, where each address corresponds to each secret key.

Before this method returns, it performs `fdatasync` on the wallet file, so if you add lots of addresses, it makes sense to batch them instead of calling this method individually per address.

#### Input (params)

Field Type Mandatory Default value Description
———————-———————–———————————————————-
`secret_spend_keys` `[]string` Yes - Array of secret spend keys.
`creation_timestamp` `uint32` No `0` Min of creation timestamps of spend keys.

#### Output

Field Type Description
———————-————————————————-
`secret_spend_keys` `[]string` Array of created secret spend keys.
`addresses` `[]string` Array of created addresses.

#### Example 1

Let's create two new addresses.

Input: ``` curl -s -u user:pass -X POST http://127.0.0.1:8070/json_rpc -H 'Content-Type: application/json-rpc' -d '{

"jsonrpc": "2.0",
"id": "0",
"method": "create_addresses",
"params": { "secret_spend_keys": ["", ""] }

}' ```

Output: ``` {

"id": "0",
"jsonrpc": "2.0",
"result": {
  "addresses": [
    "232A9qxGyKLanKmP7Q9TBA6Jv1tPx5AxM3ExRFhSijaVYVY4FtboZDSfortdXLzEqZQkan6xqXb73XiJND3tqnQY6yJMXXL",
    "275e2yS1sD6bpNCAbfZa5HH1C3FU8SZnLCSnEE2VLmdi5u373YQNsgCfortdXLzEqZQkan6xqXb73XiJND3tqnQY6stvysa"
  ],
  "secret_spend_keys": [
    "5506af58782aaae7603d80bcca0785affa2289e70242624eb3af28f8ca03bb02",
    "50b3e1b926ca731b634c6084532daf1796775ed54a91cd89371363bb43b4d907"
  ]
}

} ```

### 2. Get Addresses

#### About

Returns an array of all addresses stored in a wallet file. If `view_only` flag is `true`, there are no secret spend keys in the file, so the `walletd` is allowed to spend money from any address.

#### Input (params)

Empty

#### Output

Field Type Description
————–—————————————————–
`addresses` `[]string` Array of addresses.
`view_only` `bool` Flag indicating if wallet is view-only.

#### Example 1

Let's request all the addresses in the current wallet file.

Input:

``` curl -s -u user:pass -X POST http://127.0.0.1:8070/json_rpc -H 'Content-Type: application/json-rpc' -d '{

"jsonrpc": "2.0",
"id": "0",
"method": "get_addresses",
"params": {}

}' ```

Output: ``` {

"id": "0",
"jsonrpc": "2.0",
"result": {
  "addresses": [
    "29r79FxNVquhc3fyhoeNNy8dLnqoWdGEqhagwpG7u5hwK7SF9K6Lup4fortdXLzEqZQkan6xqXb73XiJND3tqnQY6uJTJjy",
    "275e2yS1sD6bpNCAbfZa5HH1C3FU8SZnLCSnEE2VLmdi5u373YQNsgCfortdXLzEqZQkan6xqXb73XiJND3tqnQY6stvysa",
    "232A9qxGyKLanKmP7Q9TBA6Jv1tPx5AxM3ExRFhSijaVYVY4FtboZDSfortdXLzEqZQkan6xqXb73XiJND3tqnQY6yJMXXL"
  ],
  "view_only": false
}

} ```

### 3. Get View Key Pair

#### About

Returns a view key pair common for all addresses in a wallet file.

#### Input (params)

Empty

#### Output

Field Type Description
——————-———-——————
`public_view_key` `string` Public view key.
`secret_view_key` `string` Secret view key.

#### Example 1

Let's receive a pair of view keys from the current wallet file.

Input: ``` curl -s -u user:pass -X POST http://127.0.0.1:8070/json_rpc -H 'Content-Type: application/json-rpc' -d '{

"jsonrpc": "2.0",
"id": "0",
"method": "get_view_key_pair",
"params": {}

}' ```

Output: ``` {

"id": "0",
"jsonrpc": "2.0",
"result": {
  "public_view_key": "0f8d6f0373f3c0e2dd2552fb7badb1de9cf3515614e38ef7217ed129e38cecc6",
  "secret_view_key": "8d44666882744a9f35c9d83b2ded858fddd0b140c4071aab8a8fa403828b5509"
}

} ```

### 4. Create Send Proof

#### About

Creates a send proof certifying that the money has actually been sent by the caller in a specified transaction to an address. If you leave the field `addresses` empty, you get a proof for every address used in the transaction, which is not stored in a wallet file (so no proofs for change). This works only if there is a `<wallet-file>.history` folder with the corresponding transaction history. If you set an array of addresses, you get a proof for every address actually used in a transaction. The GUI client can use the address book in an attempt to guess addresses in case there is no history stored for a particular transaction.

The field `message` is any user text. It will be included in the proof and become part of it so that changing the `message` would be impossible without destroying the proof validity. So a user can include personal info or some challenge there to prove that they have really created the proof.

Returns an array of generated proofs or empty array if no proofs has been generated (this usually happens if no money has been actually sent to specified addresses in specified transaction)

#### Input (params)

Field Type Mandatory Default value Description
——————————————–————————————
`addresses` `[]string` No `[]` Array of addresses.
`transaction_hash` `string` Yes - Transaction hash.
`message` `string` No Empty User message.

#### Output

Field Type Description
——————-————————————–
`send_proofs` `[]string` Array of created proofs.

### 5. Get balance

#### About

Gets balance of specified address (or all addresses) taking in account specified confirmation blocks count. Clients, which regard some block height as 'final', should specify that height as `height_or_depth`. Simple clients may omit `height_or_depth` altogether, or use negative value equal to desired confirmations.

Returns balanced split into 3 categories - `spendable` is the sum of all unlocked unspent non-dust outputs created prior to specified height_or_depth. `spendable_dust` is the same for dust outputs. It can be spent only by specifying anonymity `0` in `create_tranasaction` call. `locked_or_unconfirmed` is sum of all locked or unconfirmed unspent outputs.

If you need introspection into actual outputs, call [`get_unspents`](Bytecoin-Wallet-Daemon-JSON-RPC-API#9-get-unspents).

#### Input (params)

Field Type Mandatory Default value Description
——————— ———-———–———————————–
`address` `string` No Empty Address.
`height_or_depth` `int32` No `-6` Point of finality.

#### Output

Field Type Description
————————-———-————————————————————
`spendable` `uint64` Amount that can be spent with anonymity >= 0.
`spendable_dust` `uint64` Amount that can be spend with anonymity = 0.
`locked_or_unconfirmed` `uint64` Amount that will be available at some point in the future.

#### Example 1

Let's get balance for all addresses under a depth of 10 blocks.

Input: ``` curl -s -u user:pass -X POST http://127.0.0.1:8070/json_rpc -H 'Content-Type: application/json-rpc' -d '{

"jsonrpc": "2.0",
"id": "0",
"method": "get_balance",
"params": { "height_or_depth": -10 }

}' ```

Output: ``` {

"id": "0",
"jsonrpc": "2.0",
"result": {
  "locked_or_unconfirmed": 0,
  "spendable": 40000000000,
  "spendable_dust": 0
}

} ```

### Example 2

Let's get balance for address `2AGmhxRPbK3BtiyUz7vc4hHTj4n2cPdiWTHXgfHmPow5gr83GAkEsKLTE8muA6umGAEU78k7L4LmyAi7Efk4EwKoShnPYwR` over a height of 1526550.

Input: ``` curl -s -u user:pass -X POST http://127.0.0.1:8070/json_rpc -H 'Content-Type: application/json-rpc' -d '{

"jsonrpc": "2.0",
"id": "0",
"method": "get_balance",
"params": {
  "address": "2AGmhxRPbK3BtiyUz7vc4hHTj4n2cPdiWTHXgfHmPow5gr83GAkEsKLTE8muA6umGAEU78k7L4LmyAi7Efk4EwKoShnPYwR",
  "height_or_depth": 1526550
}

}' ```

Output: ``` {

"id": "0",
"jsonrpc": "2.0",
"result": {
  "locked_or_unconfirmed": 0,
  "spendable": 99000000,
  "spendable_dust": 0
}

} ```

### 6. Get status

#### About

Get status about state of walletd and bytecoind. If you specify all input parameters, and they are equal to the current state of the `walletd`, you will get response only when some of them change. Most simple way to accomplish this is just sending previous response as the next request.

#### Input (params)

Field Type Mandatory Default value Description
—————————-———-———–——————————————————————
`top_block_hash` `string` No Empty Value received in previous `get_status` response.
`transaction_pool_version` `uint32` No `0` Value received in previous `get_status` response.
`incoming_peer_count` `uint32` No `0` Value received in previous `get_status` response.
`outgoing_peer_count` `uint32` No `0` Value received in previous `get_status` response.
`lower_level_error` `string` No Empty Value received in previous `get_status` response.

#### Output

Field Type Description
———————————————-——————————————————————————————
`top_known_block_height` `uint32` Largest block height known to walletd or bytecoind.
`top_block_height` `uint32` All transaction prior to that height have been processed by walletd.
`top_block_difficulty` `uint64` Difficulty of top block.
`top_block_timestamp` `uint32` Timestamp of top block.
`top_block_hash` `string` Hash of top block.
`top_block_timestamp_median` `uint32` Median timestamp of top block.
`recommended_fee_per_byte` `uint64` Value of fee recommended.
`transaction_pool_version` `uint32` Adding or removing transaction from pool increments version.
`incoming_peer_count` `uint32` Incoming peers to bytecoind.
`outgoing_peer_count` `uint32` Outgoing peers from bytecoind.
`lower_level_error` `string` Error on lower level (bytecoind for walletd, etc).
`next_block_effective_median_size` `uint32` Created transaction raw size should be less this value, otherwise will not fit in block.

#### Example 1

Let's do a regular status request.

Input: ``` curl -s -u user:pass -X POST http://127.0.0.1:8070/json_rpc -H 'Content-Type: application/json-rpc' -d '{

"jsonrpc": "2.0",
"id": "0",
"method": "get_status",
"params": {}

}' ```

Output: ``` {

"id": "0",
"jsonrpc": "2.0",
"result": {
  "incoming_peer_count": 0,
  "lower_level_error": "",
  "next_block_effective_median_size": 100000,
  "outgoing_peer_count": 5,
  "recommended_fee_per_byte": 100,
  "top_block_difficulty": 22140079675,
  "top_block_hash": "32a2c6407b842a9d116b24320d6d055de2d0c3c97c8627792ad5394bb8749b03",
  "top_block_height": 1526026,
  "top_block_timestamp": 1525965182,
  "top_block_timestamp_median": 0,
  "top_known_block_height": 1526026,
  "transaction_pool_version": 5
}

} ```

### 7. Get transaction

#### About

Returns transaction by hash (only if it contains at least one transfer to/from any of wallet addresses).

If transaction is not found, will return a transaction with default fields (check for empty `hash` field)

#### Input (params)

Field Type Mandatory Default value Description
——–———-———–———————————–
`hash` `string` Yes - Hex of hash bytes.

#### Output

Field Type Description
——————————————————
`transaction` `Transaction` Resultant transaction.

### 8. Get transfers

#### About

This is how you iterate through the history of transfers to/from wallet addresses. If you specify address, it will filter transfers with that address (anyway you should compare address of transfer to desired address yourself, because this filter is not exact and will return excess transfers). If you set address to empty, you will get all transfers to/from any address stored in wallet file.

You specify window (`from_height` .. `to_height`), direction (`forward`) flag, and approximate chunk size (`desired_transactions_count`) to iterate through the transfer history. A bit more or less than `desired_transactions_count` can be returned, as this call always returns whole blocks. Window for the next iteration is returned as (`next_from_height` .. `next_to_height`). When this window becomes empty, iteration is finished.

If you specify window that includes `top_block + 1`, you will get transfers residing in transaction memory pool.

This method returns block only if it contains transaction we are interested into. Also transaction will be included in block only if it contains transfer we are interested into. So we get filtered view of blockchain, omitting parts which walletd cannot parse using keys stored in wallet file.

### Twists with locked outputs

Some transactions are locked until specific block height or block timestamp. When parsing returned transfers you should look into `locked` field, and if it is true, you should avoid counting incoming balance from that transfer.

In addition to blocks with transfers, this method also returns transfers from prior blocks, unlocked by block height or timestamp of blocks in window you specified. So for locked transfers, you will get them in `unlocked_transfers` as soon as they are unlocked. This is the point you should count their incoming balances.

#### Input (params)

Field Type Mandatory Default value Description
—————————————-———–———————————————————-
`address` `string` No Empty Filter by address.
`desired_transactions_count` `uint32` No `232-1` Approx. number of transactions to return.
`forward` `bool` No `false` Direction of iteration through window.
`from_height` `uint32` No `0` Start of window (not included).
`to_height` `uint32` No `232-1` End of window (included).

#### Output

Field Type Description
———————-————–———————————–
`blocks` `[]Block` Blocks from window.
`unlocked_transfers` `[]Transfer` Transfers unlocked within window.
`next_from_height` `uint32` Window for next iteration.
`next_to_height` `uint32` Window for next iteration.

### 9. Get unspents

#### About

This method returns the same information as [`get_balance`](Bytecoin-Wallet-Daemon-JSON-RPC-API#5-get-balance), but split into individual outputs. Sum of those outputs is always the result of [`get_balance`](Bytecoin-Wallet-Daemon-JSON-RPC-API#5-get-balance) call (if no changes to `walletd` state happened between those 2 calls).

Outputs corresponding to `spendable` and `spendable_dust` balance will be returned in `spendable` array, to distinguish them you should look into `output.is_dust` field.

#### Input (params)

Field Type Mandatory Default value Description
———————-———-———–———————————–
`address` `string` No Empty Address.
`height_or_depth` `int32` No `-6` Point of finality.

#### Output

Field Type Description
————————-————————————————————————-
`spendable` `[]Output` Outputs that can be spent.
`locked_or_unconfirmed` `[]Output` Outputs that will be available at some point in the future.

#### Example 1

Let's view unpsents for address `2AGmhxRPbK3BtiyUz7vc4hHTj4n2cPdiWTHXgfHmPow5gr83GAkEsKLTE8muA6umGAEU78k7L4LmyAi7Efk4EwKoShnPYwR` under a depth of 10 blocks.

Input: ``` curl -s -u user:pass -X POST http://127.0.0.1:8070/json_rpc -H 'Content-Type: application/json-rpc' -d '{

"jsonrpc": "2.0",
"id": "0",
"method": "get_unspents",
"params": {
  "address": "2AGmhxRPbK3BtiyUz7vc4hHTj4n2cPdiWTHXgfHmPow5gr83GAkEsKLTE8muA6umGAEU78k7L4LmyAi7Efk4EwKoShnPYwR",
  "height_or_depth": -10
}

}' ```

Output: ``` {

"id": "0",
"jsonrpc": "2.0",
"result": {
  "locked_or_unconfirmed": [],
  "spendable": [
    {
      "address": "2AGmhxRPbK3BtiyUz7vc4hHTj4n2cPdiWTHXgfHmPow5gr83GAkEsKLTE8muA6umGAEU78k7L4LmyAi7Efk4EwKoShnPYwR",
      "amount": 40000000000,
      "dust": false,
      "global_index": 774666,
      "height": 1525878,
      "index_in_transaction": 1,
      "key_image": "21a396a27f5b0a1355e97bff39bca3536cb2021e40fe910095cdaae70ca4aed1",
      "public_key": "e74a16298807c861bd0899b223fc3b05f1b437f84b66cf93632497748782990c",
      "transaction_public_key": "916f280847248695ef030070ad71b9cd3c6a9c36e46e6c765bbacf759f163a70",
      "unlock_time": 0
    }
  ]
}

} ```

### 10. Create transaction

#### About

Create and sign transaction by specifying transfers to make.

If you set `spend_addresses`, the call is limited to the balance of that addresses. If you leave `spend_addresses` empty, you should also set `any_spend_address` to true, as a protection against bug in your code accidentally leaving spend_address empty. In this case the call can spend all balance of all addresses in a wallet.

Usually it is impossible to find set of outputs to transfer exact sum you specify, so `change_address` is required.

`confirmed_height_or_depth` should be set to the same value you use for your [`get_balance`](Bytecoin-Wallet-Daemon-JSON-RPC-API#5-get-balance) and [`get_transfers`](Bytecoin-Wallet-Daemon-JSON-RPC-API#8-get-transfers) call. walletd selects random outputs to mix in with your outputs, and should select them from the same finality window, otherwise you risk either losing anonymity (if you set it to low) or making transaction invalid (if you set it too high and blockchain reorganization happens).

Setting `fee_per_byte` to 0 is the same as setting it to the value returned by [`get_status`](Bytecoin-Wallet-Daemon-JSON-RPC-API#6-get-status). You can use larger or smaller value to increase or decrease chance of speedy inclusion in the blockchain.

You should fill in the following fields of transaction: `anonymity`, (optional) `unlock_time`, (optional) `payment_id` and `transfer`s to make. For each transfer you should fill `address` and (positive) `amount` fields.

If you leave `optimization` field empty, walletd will use normal optimization of output denominations (fusion) when creating transaction. This works well when ratio of transactions sent to received is around 1. You can use `minimal` setting for wallets receiving far less transactions than sending, saving a bit of fees. You should use `aggressive` for wallets recieving far more transactions than sending, this setting will use every opportunity to fuse larger number of identical outputs together. As maximum transaction size is limited by block median size, you can give more room for optimization by setting anonymity to as low value as possible. Moreover, if anonymity is set to 0, wallet will prioritize optimizing out dust and crazy (large but not round) denominations of outputs.

You can set `save_history` to false if you save transfers you make in your own database. In case you need to generate send proof later, you will use transfer information from your database as an input to [`create_send_proof`](Bytecoin-Wallet-Daemon-JSON-RPC-API#4-create-send-proof) call.

You get `binary_transaction` field to later pass to [`send_transaction`](Bytecoin-Wallet-Daemon-JSON-RPC-API#11-send-transaction), and `transaction` field for inspecting fee and size before sending. `save_history_error` is reported, usually as a result of storing wallet on read-only media.

#### Input (params)

Field Type Mandatory Default value Description
—————————–————————–———————————————————–
`transaction` `Transaction` Yes - Partly filled transaction.
`spend_addresses` `[]string` No Empty Addresses money will be withdrawn from.
`any_spend_address` `bool` No `false` Required if `spend_address` empty.
`change_address` `string` Yes - Address where the change will be sent to.
`confirmed_height_or_depth` `int32` No `-6` Confirmed point of finality.
`fee_per_byte` `int64` No `0` 0 to use recommended value.
`optimization` `string` No Empty Optimization (fusion) level.
`save_history` `bool` No `true` Flag to indicate storing transfer history.

#### Output

Field Type Description
———————-————————————————–
`binary_transaction` `string` Hex of binary transaction bytes.
`transaction` `Transaction` Transaction for inspecting.
`save_history_error` `string` Only not empty for an error.

#### Example 1

Let's create a transaction, which transfers `100000000` AU to address `29G3eSESciB1m7pqJdxYyfFTBLe2i5miycP4XmgUb3npM6aZC5P35SBMkZ6uqNKMuM8D13UM7J5x1iJFbTvCGUEyBft3ajD` from address `2AGmhxRPbK3BtiyUz7vc4hHTj4n2cPdiWTHXgfHmPow5gr83GAkEsKLTE8muA6umGAEU78k7L4LmyAi7Efk4EwKoShnPYwR` and returns change to address `21JAGNBAxDfJYJ61GBiAEXKV9k3J4EqXLE2XHjKPMLHeZey7fTY2ip6TE8muA6umGAEU78k7L4LmyAi7Efk4EwKoSe7rzPe`.

Input: ``` curl -s -u user:pass -X POST http://127.0.0.1:8070/json_rpc -H 'Content-Type: application/json-rpc' -d '{

"jsonrpc": "2.0",
"id": "0",
"method": "create_transaction",
"params": {
  "transaction": {
    "anonymity": 6,
    "payment_id": "",
    "transfers": [
      {
        "address": "29G3eSESciB1m7pqJdxYyfFTBLe2i5miycP4XmgUb3npM6aZC5P35SBMkZ6uqNKMuM8D13UM7J5x1iJFbTvCGUEyBft3ajD",
        "amount": 100000000
      }
    ]
  },
  "spend_addresses": [
    "2AGmhxRPbK3BtiyUz7vc4hHTj4n2cPdiWTHXgfHmPow5gr83GAkEsKLTE8muA6umGAEU78k7L4LmyAi7Efk4EwKoShnPYwR"
  ],
  "change_address": "21JAGNBAxDfJYJ61GBiAEXKV9k3J4EqXLE2XHjKPMLHeZey7fTY2ip6TE8muA6umGAEU78k7L4LmyAi7Efk4EwKoSe7rzPe",
  "optimization": "minimal"
}

}' ```

Output: ``` TODO ```

### 11. Send transaction

#### About

Place the (previously created) transaction into the memory pool for immediate sending to the p2p network. Note, that if bytecoind is not connected to internet, this method will nevertheless succeed. Moreover, in the situation of high transaction traffic your transaction may be eventually displaced from the memory pools of all nodes in the network.

Result of call will be `broadcast`, if transaction was successfully placed into the memory pool. Result of call will be `increasefee`, if the memory pool was full and fee was not enough to displace another transaction from pool.

#### Input (params)

Field Type Mandatory Default value Description
—————————————-———–————————————————-
`binary_transaction` `string` Yes - Hex of binary transaction bytes.

#### Output

Field Type Description
———————-————–——————
`send_result` `string` Result of call.

### 12. Check Send Proof

#### About

Checks that given send proof is valid and correct.

Result of the call will be empty value of `validation_error`, if the given proof is correct.

#### Input (params)

Field Type Mandatory Default value Description
—————————————-———–————————————————-
`send_proof` `string` Yes - A send proof to check.

#### Output

Field Type Description
———————-————–————————————————–
`validation_error` `string` Result of call. Empty, if the proof is correct.

#### Example 1

Let's check a send proof, created by the `create_send_proof` method.

Input: ``` curl -s -u user:pass -X POST http://127.0.0.1:8070/json_rpc -H 'Content-Type: application/json-rpc' -d '{

"jsonrpc": "2.0",
"id": "0",
"method": "check_send_proof",
"params": {
  "send_proof": "{\"address\":\"25EQfFBJ7FzEDKaEWVjkHtF3u3G8bB7WcbMzjtyCQYyu6hUCCxT3jf76e5Fy5eS9Ao8rt5pch3JA4GWiwRw5aBxWF8D99PB\",\"amount\":500000000,\"message\":\"We HODL!\",\"proof\":\"XW1FoL55kFRXZGiUCphVPH8kmSzC9cv3WXhQD33dZXQw6V8to48ycZriSdPJQkUVRc5fE7cB3vpa98vKMfVPQekWMWNKze5TdH9EnPHUo4XNnSRPj9KWDcdsVaBARKWRPtBF\",\"transaction_hash\":\"b8ac7af5098bb304fa2e7b383d2192a3a63eda217092113b6a4ce625e419c046\"}"
}

}' ``` Output: ``` {

"id": "0",
"jsonrpc": "2.0",
"result": {
  "validation_error": ""
}

} ```


2) Service location

By default, Bytecoin Node Service (bytecoind, Node Daemon) is bound only to 127.0.0.1 (localhost) interface, so can be accessed only from the same computer it runs on. This is done to reduce number of external attack vectors. bytecoind itself has access to only public information, but it sometimes runs in the same process with walletd, which has access to wallet keys. To bind to all interfaces, use –bytecoind-bind-address=0.0.0.0:8081 command line argument (specifying port is mandatory).

To make a JSON PRC request to the bytecoind you should make an HTTP POST request to an entry point:

http:<ip>:<port>/json_rpc where: <ip> is IPv4 address of bytecoind service. If the service is on local machine, use 127.0.0.1 instead of localhost. <port> is TCP port of bytecoind. By default the service is bound to 8081. Curl template curl -s -u <user>:<pass> -X POST http:<ip>:<port>/json_rpc -H 'Content-Type: application/json-rpc' -d '{“jsonrpc”: “2.0”, “id”: “<id>”, “method”: “<method>”, “params”: {<params>}}'

Methods

Getting information about blockchain

Method Description

get_status Returns status of bytecoind. sync_blocks Gets blockchain blocks for walletd and block explorer sync. sync_mem_pool Gets difference to transaction pool. check_send_proof Checks validity of send proof. Creating transactions Method Description get_random_outputs Is used by walletd to get mix-ins when building transaction. send_transaction Adds transaction to pool. Usually should be called through walletd. Mining (new version) Method Description get_currency_id Returns hash of genesis block. get_block_template Gets block for mining. submit_block Submits mined block. Mining (legacy version) Method Description getcurrencyid Returns hash of genesis block. getblocktemplate Gets block for mining. submitblock Submits mined block. getlastblockheader Gets last block header. getblockheaderbyhash Gets block header by hash. getblockheaderbyheight Gets block header by height. Warning: This legacy method starts counting from 1, so if you set height to 5000, you will get header with height 4999.

3) Design notes

Bytecoin is split into two separate services - bytecoind and walletd. This is a direct consequence of the anonymity concept Bytecoin is built upon.

bytecoind service is responsible for P2P connections and consensus, it can assemble transactions into blocks, check transactions validity, synchronize and grow blockchain, but it cannot look inside transactions to see transfers between addresses, because this requires access to user secrets (wallet) to do so.

Here comes walletd that is designed to work with user wallet being run with a wallet file as a mandatory argument. After getting chain of blocks from bytecoind, walletd sifts through all transactions with wallet keys to see transfers from and to addresses stored in that wallet file.

Though this separation is perfect, the most common case is running bytecoind and walletd on the same computer at the same time. That's why walletd has a local copy of bytecoind built-in. If you run walletd without –bytecoind-remote-address=<ip:port> parameter, it will run in-process bytecoind while walletd itself is running. If you run walletd with –bytecoind-remote-address=<ip:port>, it will try to connect to external bytecoind running at the given remote address.

You cannot have several bytecoinds running on the same machine, because bytecoind requires exclusive access to blockchain database stored in Bytecoin data folder. (kind-of exception is running one for mainnet and one for testnet, this works because there is separate Bytecoin data folder for testnet)

In the meantime, you can have as many walletds running as you need, but the same wallet file (actually, wallet file with the same view key) cannot be open by more than one walletd. This is because walletd requires exclusive access to wallet cache database with a name derived from wallet file view key, stored in Bytecoin data folder.

Security notice: If you operate large sums of money, you should always run bytecoind in separate process, so that potential attacks exploiting security vulnerabilities in p2p network code will not get access to address space where wallet keys are stored.

Note about secrets on command line: walletd requires wallet password and HTTP basic authentication parameters to be used by JSON API. It expects them from the standard input (typed by user after launching), because secrets on a command line are security risk. So, if you wish to run walletd from script without user interaction, you should run it like this:

On Linux and Mac OSX $ echo -e “<wallet_password>\n<http_user>:<http_password>” | ./walletd <other parameters> On Windows C:\> (echo <wallet_password> & echo <http_user>:<http_password>) | ./walletd <other parameters> On Windows, if wallet password is empty, we need special syntax to echo empty line C:\> (echo( & echo <http_user>:<http_password>) | ./walletd <other parameters> Handy examples Running a single walletd with built-in bytecoind and default parameters:

$ ./walletd –wallet-file=<file> Running a single walletd with external bytecoind on the same machine (in beta you can only use 127.0.0.1 instead of localhost):

$ ./bytecoind $ ./walletd –wallet-file=<file> –bytecoind-remote-address=127.0.0.1:8081 Running a single walletd with external bytecoind on a different machine (if not using https, you can only use IP-address):

$ ./bytecoind $ ./walletd –wallet-file=<file> –bytecoind-remote-address=137.28.14.69:8081 Running two walletds with external bytecoind on the same machine:

$ ./bytecoind $ ./walletd –wallet-file=<file1> –bytecoind-remote-address=127.0.0.1:8081 $ ./walletd –wallet-file=<file2> –walletd-bind-address=127.0.0.1:8071 –bytecoind-remote-address=127.0.0.1:8081 We had to specify different bind port for accessing second walletd, because port 8070 is already used by first walletd.

We can check them both in GUI wallet, selecting “Connect to remote walletd” command in Wallet menu, and typing 127.0.0.1:8070 or 127.0.0.1:8071 to connect to each of running walletds.

Running walletd with external bytecoind on a remote server via https (when using https, you can only use full DNS name):

$ ./walletd –wallet-file=<file> –bytecoind-remote-address=https://node123.amazon.com:8091 On your server, you should run bytecoind normally with Nginx HTTPS proxy (or amazon load balancer) configured with valid certificate (https://letsencrypt.org is a popular option), listening on port 8091 and redirecting requests to bytecoind that listens on port 8081.

4) Incoming payment processing for e-shop or exchange

Overall description

We presume that blockchain will never be reorganized beyond n_confirmations constant, we predefine.

We store finality_height in the database with initial value of 0. When the blockchain is advanced, we move finality_height forward, trailing top block height by n_confirmations and getting all transfers between old and new finality_height in the process, then modifying incoming balances of corresponding addresses in the database. When the blockchain is retracted, we keep finality_height as is. Can blockchain be really retracted? First, if some side chain grows beyond main chain, main chain is temporarily retracted. Second, if walletd or bytecoind database is erased (probably as a part of version upgrade), or restored from earlier backup. In any case, blockchain height will soon increase and we will continue advancing our finality_height. Here is an infinite loop to track incoming funds (pseudocode):

const n_confirmations = 10 var status while true:

var was_hash = status.top_block_hash
var was_pool_version = status.transaction_pool_version
status = WALLETD.get_status(status) // waits for changes to status
// code to update confirmed transaction in our DB for order processing
if status.top_block_height > DB.finality_height + n_confirmations:
  result = WALLETD.get_transfers(from_height: DB.finality_height, to_height: status.top_block_height - n_confirmations)
  DB.begin_transaction()
  foreach block in result.blocks:
    foreach tx in block.transactions:
      foreach transfer in tx.transfers:
        if (not transfer.locked) and transfer.ours and transfer.amount > 0:
          DB.add_incoming_confirmed(transfer.address, transfer.amount, tx)
    foreach transfer in result.unlocked_transfers:
      if transfer.ours and transfer.amount > 0:
        DB.add_incoming_confirmed(transfer.address, transfer.amount, null) // this transfer is result of unlock
    DB.finality_height = status.top_block_height - n_confirmations
    DB.commit_transaction()
// code to update unconfirmed transaction in our DB for showing in user's account web interface
if status.top_block_hash != was_hash or status.transaction_pool_version != was_pool_version:
  result = WALLETD.get_transfers(from_height: DB.finality_height)
  DB.begin_transaction()
  DB.clear_unconfirmed()
  foreach block in result.blocks:
    foreach tx in block.transactions:
      foreach transfer in tx.transfers:
        if (not transfer.locked) and transfer.ours and transfer.amount > 0:
          DB.add_incoming_unconfirmed(transfer.address, transfer.amount, tx)
    DB.commit_transaction()

When the order is created by user in e-shop, or user needs a new incoming address on an exchange, we create and associate a new address like this (pseudocode):

result = WALLETD.create_addresses([""]) // create 1 new address
DB.begin_transaction()
DB.save_address_keys(result.spend_keys[0]) // we store keys in our db for backup
DB.create_order(order_data, result.addresses[0])
DB.commit_transaction()

In e-shop when the incoming balance of address corresponding to some order reaches order price, we decrease incoming balance and set the order for shipment. In an exchange, incoming funds become directly available to the user as soon as they are confirmed.

5) Introduction

Historically Bytecoin uses various formats for storing keys. Current version is V2, it is used by old GUI wallet and old Payment Gate daemon. The new Bytecoin also uses V2 file format with some twists (see below).

File structure Wallet file is designed to store a list of addresses (minimum one) with corresponding keys and is encrypted with ChaCha8 algorithm. Specifying no password encrypts with a key derived from the empty string.

Each address has a unique spend key pair, but they all share the common view key pair, so from user's perspective, all addresses stored in a single wallet file will have a common right half of address string.

Common view key pair is on purpose. In Bytecoin transactions are anonymous, finding transactions corresponding to some address requires scanning all transaction in blockchain performing slow computations per view key part of the address. Several dozens of different view keys would be enough to exceed modern PC processing capabilities.

Creation timestamp is also stored in wallet file, this allows skipping scanning (significant) part of blockchain prior to the wallet creation.

Deterministic vs non-deterministic V2 wallet file uses non-deterministic key generation, each key is random. So you should back up wallet file after adding addresses to it, otherwise you risk losing keys for new addresses. This will change in V3.

View-only wallet View-only wallet file is created by zeroing private spend keys in existing wallet file. When such a file is open by walletd, it allows viewing transaction corresponding to addresses it stores, but does not allow spending.

Transaction history In Bytecoin, if you do not save addresses you sent money to, you cannot get this information later from blockchain and reveal those addresses. That's why transaction history is an important component being worth backing up.

The old Bytecoin stores history of transactions it sent in the tail section of V2 file, right after keys. In contrast, the new Bytecoin stores history in the <wallet_file>.history folder adjacent to the wallet file in separate files per transaction. You should back up this folder periodically otherwise you risk losing your history.

Interoperability with old Bytecoin The old Bytecoin's walletd stores wallet cache (megabytes or more) in the tail section of V2 wallet file, after keys and history. The new Bytecoin's walletd stores wallet cache in 'wallet_cache' folder located in the Coin Folder, keeping wallet file very small (~100 bytes per address).

You can make new Bytecoin's walletd truncate the tail section of V2 wallet file by changing wallet file password.

Opening such file by an old Bytecoin will make it rescan blockchain recreating wallet cache in tail section.

Interoperability with simplewallet simplewallet uses V1 wallet file format. The new Bytecoin's walletd will open V1 file, but overwrite it with V2 format on any modification (e.g. adding addresses or changing password). After that simplewallet will not be able to open the file.