Let’s say I’m an asset owner (the person who issued the asset (token), or if the token was transferred, the last transferee) who wants to pay a dividend to all addresses that hold my token (except the owner’s address) and I want to use the API for that.
Using the API, I have to do the following:
-
Create a dividend transaction using the Counterparty API
create_dividend
method - Counterparty API then returns a raw transaction, which I need to sign using a bitcoin wallet
- Having a signed transaction, send (broadcast) it to the bitcoin network
Create a dividend transaction
You should at least take a look at the Counterparty API documentation, because I won’t repeat that content here.
Basically the parameters are dividend_asset
(what I am paying my dividend in), asset
(for which token/asset I’m paying the dividend) and source
(which must be the asset owner’s address.
Here’s an example from testnet:
- I’m paying dividend for
DIVTEST
(which I own atmofv...
) using BTC. - WARNING WARNING WARNING: you must keep in mind that in the API for Divisible (such as BTC) assets, the amount is in 100-millionth fractions (e.g.s satoshis), while for Indivisible assets (which can be quoted only in whole units), it is the absolute amount. This is different from Counterwallet and the CLI which takes care of that conversion for you.
- Here I’m paying dividend in BTC (a Divisible asset) so
quantity_per_unit
of 100,000 means that the holders ofDIVTEST
will get 0.0001 BTC (100,000/100,000,000) for each unit ofDIVTEST
they possess. If I were to use an indivisible coin fordividend_asset
here, thenquantity_per_unit: 100
would mean each holder ofDIVTEST
would get 100 ofdividend_asset
. - Examples:
- In this example: Donald owns 123.4 DIVTEST and I’m paying a dividend of 0.001 BTC per each. She’ll receive 123.4 * 0.001 BTC to her DIVTEST address
- With the dividend paid in indivisible asset (e.g. a token called
MOVIETICKET
), maybe I’d pay 3 tokens per each unit of DIVTEST held, so Donald would receive 123.4 * 3 of 370.2 (actually 370, sinceMOVIETICKET
isn’t divisible) of the dividend token.
{"jsonrpc": "2.0", "params": {"dividend_asset": "BTC", "asset": "DIVTEST", "quantity_per_unit": 100000, "source": "mofvU5ypG4CXBkgAZoUEcup9LkASr6V3eT"}, "method": "create_dividend", "id": 0}
Change the parameters and put it in a curl or a script such as Python. There are examples for other methods in here:
http://counterparty.io/docs/api/#example-implementations-for-json-rpc-api
Now run this script against a Counterparty API server (for testnet or mainnet), and it will return a raw unsigned transaction to you.
{
"id": 0,
"jsonrpc": "2.0",
"result": "0100000001437fcd704435f894184effd2506093490ae1300c981c797b7777de7372348635020000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588acffffffff028c230000000000001976a9147a80c2e066cc7cf14f9db8c5331bc86acffcb1ec88acf1377200000000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588ac00000000"
}
If you don’t trust the server, or want to confirm what the hell is packed inside of this transaction, you can decode the transaction before you sign & send. An exercise for the reader, as they say.
Sign the Transaction
Most wallets, including Bitcoin Core, can sign transactions. Of course you need to have the address (and its private key) in the wallet, otherwise it won’t be able to sign it (if you want to import an address to Bitcoin Core wallet, seek help on importprivkey
).
That’s why one cannot just copy and paste command examples below - they are based on the inputs from the JSON string above.
Example for Bitcoin (testnet):
bitcoin-cli -testnet signrawtransaction "0100000001437fcd704435f894184effd2506093490ae1300c981c797b7777de7372348635020000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588acffffffff028c230000000000001976a9147a80c2e066cc7cf14f9db8c5331bc86acffcb1ec88acf1377200000000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588ac00000000"
Send (Broadcast)
You can broadcast the signed transaction using the sendrawtransaction
command. Its input is the output of the previous (signrawtransaction
) command above.
Practice Before You Pay
As with all actions, there is no undo (at least not on the bitcoin blockchain). Practice on testnet as long as necessary.
There’s a similar tutorial for create_send
and there’s a short intro about getting started with the API as well as these instructions specific to CoinDaddy’s public API server.
The technically easiest way to pay a dividend is to use a wallet that allows that. There are other ways (for example you can install Bitcoin Core addrindex version and counterparty-cli and complete this with one line command (counterparty-client dividend --source mofvU5ypG4CXBkgAZoUEcup9LkASr6V3eT --quantity-per-unit 0.001 --asset DIVTEST --dividend-asset XCP
(again, unlike in the API, here quantity-per-unit 0.001
means 0.001 and 100,000 would mean 100K).
But if you don’t want to download 100+ GB of blockchain data to pay dividend and have no access to a wallet that lets you, with a bit of practice and care, that can be successfully accomplished within minutes using the API. In this how-to I used Bitcoin Core (i.e. I probably downloaded at least a pruned blockchain), but you can sign the transaction with any wallet - including “thin” or SPV wallets - and broadcast it trustlessly from most public servers or ask a friend with full node to do it for you.
Appendix: Complete Example on Testnet
Counterparty API: create_dividend
- Dividend of 0.01 XCP per 1 DIVTEST held to all holders except the owner (
mofvU5ypG4CXBkgAZoUEcup9LkASr6V3eT
) - Using CoinDaddy’s public API server on testnet
JSON-RPC:
{"jsonrpc": "2.0", "params": {"dividend_asset": "XCP", "asset": "DIVTEST", "quantity_per_unit": 1000000, "source": "mofvU5ypG4CXBkgAZoUEcup9LkASr6V3eT"}
Complete curl command:
curl -X POST http://public.coindaddy.io:14000/api/ --user rpc:1234 -H 'Content-Type: application/json; charset=UTF-8' -H 'Accept: application/json, text/javascript' --data-binary '{"jsonrpc": "2.0", "params": {"dividend_asset": "XCP", "asset": "DIVTEST", "quantity_per_unit": 1000000, "source": "mofvU5ypG4CXBkgAZoUEcup9LkASr6V3eT"}, "method": "create_dividend", "id": 0}'
Raw unsigned transaction:
{
"id": 0,
"jsonrpc": "2.0",
"result": "01000000018c4088a797ff8c2e71ebfccbb245ae2db47c6d0c8b7289cad688a113ec064ccb020000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588acffffffff020000000000000000266a242d21123c24d80e010fb00d9f5e7220f5b1e3088555d5119b44bf5e57cc258f6b1826d3c715267200000000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588ac00000000"
}
Bitcoin Wallet: Sign
Using bitcoin-cli on testnet:
signrawtransaction 01000000018c4088a797ff8c2e71ebfccbb245ae2db47c6d0c8b7289cad688a113ec064ccb020000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588acffffffff020000000000000000266a242d21123c24d80e010fb00d9f5e7220f5b1e3088555d5119b44bf5e57cc258f6b1826d3c715267200000000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588ac00000000
Response:
{
"hex": "01000000018c4088a797ff8c2e71ebfccbb245ae2db47c6d0c8b7289cad688a113ec064ccb020000006b483045022100df99c95e53295c0b294b894a8cdea7aa6b80a082cfab7984adabfe72cf87546e02200ef98cfef882a8baa1cf144a730fc38a84167bb414928e96d850b927ef296d13012103d375cd4077faa8d95298b6e55825bac37ed73339585f84767527efacb25872dbffffffff020000000000000000266a242d21123c24d80e010fb00d9f5e7220f5b1e3088555d5119b44bf5e57cc258f6b1826d3c715267200000000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588ac00000000",
"complete": true
}
Bitcoin Wallet: Send
Using bitcoin-cli on testnet:
sendrawtransaction "01000000018c4088a797ff8c2e71ebfccbb245ae2db47c6d0c8b7289cad688a113ec064ccb020000006b483045022100df99c95e53295c0b294b894a8cdea7aa6b80a082cfab7984adabfe72cf87546e02200ef98cfef882a8baa1cf144a730fc38a84167bb414928e96d850b927ef296d13012103d375cd4077faa8d95298b6e55825bac37ed73339585f84767527efacb25872dbffffffff020000000000000000266a242d21123c24d80e010fb00d9f5e7220f5b1e3088555d5119b44bf5e57cc258f6b1826d3c715267200000000001976a9145973398cc2f7852166c1d3770e5d9754f2f9509588ac00000000"
Response (the hash of the transaction we sent to the network):
67831c7d055e897db9510adbc7c922f003b5cf676ba60c2f2591ca42440e9f38
Verify
Search for your address or the transaction hash. Use the mainnet URL for mainnet (doh!).
2017-01-19-T13:51:59+0800 [INFO] Dividend: mofvU5ypG4CXBkgAZoUEcup9LkASr6V3eT paid 0.01 XCP per unit of DIVTEST (67831c7d055e897db9510adbc7c922f003b5cf676ba60c2f2591ca42440e9f38) [valid]
Edit: interestingly there’s something wrong with the explorer so the above transaction is not valid.
However you could use the API or CLI to check the transaction:
$ counterparty-client --testnet getrows --table dividends --filter 'source' '=' 'mofvU5ypG4CXBkgAZoUEcup9LkASr6V3eT'