Coinstack And Public Bitcoin Blockchain

1. Block and Blockchain

Blockchain is the distributed database, which is designed to prohibit any intentional manipulation from an administrator or user. Unlike an ordinary database, Blockchain is comprised of thousands of operative nodes, but a central coordinator to control these voluntary nodes is unnecessary. Blockchain can be abbreviated to the distributed ledger to save transactions, the transaction is saved to a block, and the block is shared by all nodes. The blocks are linked like a chain, that is, Blockchain.

2. Addresses

If you want to use a Blockchain service or Bitcoin, you should create an address. The address indicates your identity on the Bitcoin network. Using the address, which is different with a private key that is explained below, you can send your Bitcoins or get Bitcoins from another user address. In Blockchain applications, the address conducts diverse roles. For example, in the Time Stamp Authority, TSA, service, the address stores a hash value of the document to verify itself. Also, when you make use of the address as a private authentication, it can be a reservoir to store an authentication certificate. The address is established by Elliptic Curve Digital Signature Algorithm, ECDSA, that is, a sort of encryption, so it can be conjugated by varied services.

2.1. Create Address

When you create an address, you should create a private key and public key under ECDSA. A sequence of creation is below: Generate random number -> Create the private key -> Create the public key -> Create the Bitcoin address

2.2. Create Private Key

The private key is a random integer from 1 to 2^256.

Generally, the private is encoded by Base58Check, which is called the private key Wallet Import Format, WIF, in Bitcoin.

WIF is shorter, and a confusable character, '1' and 'i', is removed usefully.

Shown below is a method of Coinstack to create a new private key.

Java
// create new private key
String newPrivateKeyWIF = ECKey.createNewPrivateKey();
assertNotNull(newPrivateKeyWIF);

2.3. Create Public Key and Bitcoin Address

The public key is generated by a function of ECDSA, secp256k1, with the private key as input, and the result is represented by the x, y coordinates.

It is the public key that the value is to adhere the x, y coordinates with a prefix.

The Bitcoin address is then encoded with the public key by a function, RIPEMD160(SHA256(K)).

Shown below is a sample using Coinstack to create a new address.

Java
// create new address
String newAddress = ECKey.deriveAddress(newPrivateKeyWIF);
assertNotNull(newAddress);

2.4. Check Address Balance

In the address, there is Bitcoin or OP_RETURN data. You can check your total Bitcoin of spread UTXOs.

Shell
YOUR_API_TOKEN_KEY="YOUR_API_TOKEN_KEY"
YOUR_WALLET_ADDRESS="YOUR_WALLET_ADDRESS"

curl https://mainnet.cloudwallet.io/addresses/$YOUR_WALLET_ADDRESS/balance \
    -H "apiKey: $YOUR_API_TOKEN_KEY"
Java
long balance = coinStackClient.getBalance("YOUR_WALLET_ADDRESS");
JavaScript
coinstackclient.getBalance("YOUR_WALLET_ADDRESS", function(err, balance) {
    console.log(balance);
});
Meteor
// server
var balance = coinstackclient.getBalanceSync("YOUR_WALLET_ADDRESS");
console.log(balance);
// client
coinstackclient.getBalance("YOUR_BLOCKCHAIN_ADDRESS", function(err, balance) {
    console.log(balance);
});

The result is returned as JSON type like below.

{"balance":566368820}

2.5. Check Transactions of Address

As we have seen, the address has Bitcoin or OP_RETURN data. Next is the method to check a history of Bitcoin transaction or data of OP_RETURN.

Shell
curl https://mainnet.cloudwallet.io/addresses/YOUR_WALLET_ADDRESS/history \
    -H "apiKey: YOUR_API_TOKEN_KEY"
Java
String[] transactions = coinStackClient.getTransactions("YOUR_WALLET_ADDRESS");
JavaScript
coinstackclient.getTransactions("YOUR_WALLET_ADDRESS", function(err, result) {
    console.log('result', result);
});
Meteor
// server
var result = coinstackclient.getTransactionsSync("YOUR_WALLET_ADDRESS");
console.log('result', result);

// client
coinstackclient.getTransactions("YOUR_WALLET_ADDRESS", function(err, result) {
    console.log('result', result);
});

The result is returned as JSON type like below.

[
"4fe42d98bdede1eedb504c48a7670b18b1d3691ae140d313e529ab92d53c7aa0",
"ed7b57daba7621e726eab433823faa107cc20fdfe6c53c322288cb4161d850c1",
"438e2eb76d23b3238b372fc890fc296cf26bef45a6c456a03d6d382f9814130e",
"b9a7821bb85d17c1ae0cc985846cfd6dc9a6b21ed9b5d256e8c83724458979b7",
"e67a77216cd8a68961b349b1d44a70507e42f9041f26170fb6cb411dae532139",
"5bf0f9050a8bfcd541061285581fd920ed920d49fbeb3307e3df4bcdaed1e6d8",
"34fa72fc6705f5b4db83632dde655b723ce1cceee1ef0afdf1ed6e477bd8f1fa",
"c295cd46e9757a19117c6e4c71375478df41e116fed2de641ee5985c4a99b39c",
"0648e1a672faa43ec8d2109cc97f49dfde66b4e6a786aeed9ca423fd45093009",
"f4a688452cea941c23f7169bd055cfcb107c9ff7028e6578a8bcaaa5d9058b48",
...
]

2.6. Check Unspent Outputs of Address

In Blockchain, a balance of the address is not stored, but only the history of transactions of the address is saved. An output of the transaction is two types; spent output and unspent output. The unspent output named as UTXO should be an input for a new transaction. Hence, Coinstack provides an API to search UTXOs of the address.

Shell
curl https://mainnet.cloudwallet.io/addresses/YOUR_WALLET_ADDRESS/unspentoutputs \
    -H "apiKey: YOUR_API_TOKEN_KEY"
Java
Output[] outputs = coinStackClient.getUnspentOutputs("YOUR_WALLET_ADDRESS");
JavaScript
coinStackClient.getUnspentOutputs("YOUR_WALLET_ADDRESS", function(err, result) {
    console.log('result', result);
});
Meteor
// server
var result = coinstackclient.getUnspentOutputsSync("YOUR_WALLET_ADDRESS");
console.log('result', result);
// client
coinstackclient.getUnspentOutputs("YOUR_WALLET_ADDRESS", function(err, result) {
    console.log('result', result);
});

The result is returned as JSON type like below.

[
    {
        "transaction_hash": "f2020daaf62e03deb2c6f8a94988a6cca3d66273dc6fa2169e88f02b288520ea",
        "index": 1,
        "value": "7259033307",
        "script": "76a914a13ca67f70cc4afefd4057f87d1e433dab05a20788ac",
        "confirmations": 2509
    },
    {
        "transaction_hash": "9b30059da6517a08034c0faf3bd347a7a24189285fa80ede850ecc552d165620",
        "index": 1,
        "value": "299990000",
        "script": "76a914a13ca67f70cc4afefd4057f87d1e433dab05a20788ac",
        "confirmations": 99
    },
    {
        "transaction_hash": "9ac9ab9285ebb5107bfc2e086d35c3ebefd9a899722039fac667e6ece3b20c90",
        "index": 1,
        "value": "961900000",
        "script": "76a914a13ca67f70cc4afefd4057f87d1e433dab05a20788ac",
        "confirmations": 91
    }
]

3. Transactions

3.1. Check Transaction

The transaction that belonged to Block already or requested to the Bitcoin network can be inquired by its ID.

Shell
curl https://mainnet.cloudwallet.io/transactions/YOUR_TRANSACTION_ID \
    -H "apiKey: YOUR_API_TOKEN_KEY"
Java
Transaction tx = coinStackclient.getTransaction("YOUR_TRANSACTION_ID");
JavaScript
coinstackclient.getTransaction("YOUR_TRANSACTION_ID", function(err, result) {
    console.log('result', result);
});
Meteor
// server
var result = coinstackclient.getTransactionSync("YOUR_TRANSACTION_ID");
console.log(result.transaction_hash, result.inputs);
// client
coinstackclient.getTransaction("YOUR_TRANSACTION_ID", function(err, result) {
    console.log('result', result);
});

The result is returned as JSON type like below or as a specific object of each SDK.

{
    "transaction_hash": "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87",
    "block_hash": [
        {
            "block_hash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",
            "block_height": 100000
        }
    ],
    "coinbase": true,
    "inputs": [
        {
            "transaction_hash": "0000000000000000000000000000000000000000000000000000000000000000",
            "output_index": -1,
            "address": [
            ],
            "value": ""
        }
    ],
    "outputs": [
        {
            "index": 0,
            "address": [
                "1HWqMzw1jfpXb3xyuUZ4uWXY4tqL2cW47J"
            ],
            "value": "5000000000",
            "script": "41041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac",
            "used": false
        }
    ],
    "time": "2010-12-29T11:57:43Z",
    "broadcast_time": "0001-01-01T00:00:00Z",
    "addresses": [
        "1HWqMzw1jfpXb3xyuUZ4uWXY4tqL2cW47J"
    ]
}

3.2. Create Transaction

Using the transaction, Bitcoin or an arbitrary data can be conveyed or stored to other addresses.

3.2.1. Check Unspent Output

When you create a new transaction, first of all, you should check the unspent output, UTXO, of the address, which would be used as an input of the new transaction.

UTXOs of the address are checked automatically when a transaction is generated by a transaction builder of SDK.

3.2.2. Normal Transaction

The transaction is used to transit Bitcoin normally. The target address to get Bitcoin and amounts of Bitcoin should be set.

Minute amounts of Bitcoin would be ignored by a policy named as "dust threshold", which is different by a Bitcoin client.

The transaction builder of the Coinstack SDK also throws on error when the amounts of Bitcoin is too small, which the amounts can be configured. The default value of dust threshold of the Coinstack SDK is 546 Satoshi.

3.2.3. Transaction with Data

You can store arbitrary data in the transaction using an output script called OP_RETURN instead of Bitcoin.

The transaction builder of the Coinstack SDK provides an interface to store data in the Blockchain.

Features of Coinstack SDK such as the stamping and Open Assets are developed with OP_RETURN.

3.3. Send Transaction

3.3.1. Sign

The transaction should be encrypted by a private key of the address that holds unspent outputs that would be included in the transaction.

3.3.2. Send

The signed transaction could be sent to the Bitcoin network. If a problem or error occurs during sending or the transaction itself, you can check a cause using a returning error code.

If any error isn't found in the transaction itself, you can re-send it until success.

Java
// create normal transaction
import io.blocko.coinstack.*;
import io.blocko.coinstack.exception.CoinStackException;

String privateKeyWIF = ECKey.createNewPrivateKey();
String bitcoinAddress = ECKey.deriveAddress(privateKeyWIF);
String to = bitcoinAddress;

long amount = io.blocko.coinstack.Math.convertToSatoshi("0.0002");
long fee = io.blocko.coinstack.Math.convertToSatoshi("0.0001");

TransactionBuilder builder = new TransactionBuilder();
builder.addOutput(to, amount);

String signedTx;

try {
    builder.setFee(fee);
    signedTx = coinStackClient.createSignedTransaction(builder, privateKeyWIF);
    coinStackClient.sendTransaction(signedTx);
} catch (IOException e) {
    e.printStackTrace();
} catch (CoinStackException e) {
    e.printStackTrace();
}

// get transaction id
String txid = TransactionUtil.getTransactionHash(signedTx);
// create data transaction
import io.blocko.coinstack.*;
import io.blocko.coinstack.exception.CoinStackException;

String privateKeyWIF = ECKey.createNewPrivateKey();
String bitcoinAddress = ECKey.deriveAddress(privateKeyWIF);
String to = bitcoinAddress;

long amount = io.blocko.coinstack.Math.convertToSatoshi("0.0002");
long fee = io.blocko.coinstack.Math.convertToSatoshi("0.0001");

TransactionBuilder builder = new TransactionBuilder();
builder.allowDustyOutput(true);
builder.shuffleOutputs(false);
builder.addOutput(to, amount);
builder.setData("testdata".getBytes());

String signedTx;

try {
    builder.setFee(fee);
    signedTx = coinStackClient.createSignedTransaction(builder, privateKeyWIF);
    coinStackClient.sendTransaction(signedTx);
} catch (IOException e) {
    e.printStackTrace();
} catch (CoinStackException e) {
    e.printStackTrace();
}

// get transaction id
String txid = TransactionUtil.getTransactionHash(signedTx);
JavaScript
// create transaction
var txBuilder = coinstackclient.createTransactionBuilder();
txBuilder.addOutput("TO_ADDRESS1", coinstackclient.Math.toSatoshi("0.01"));
txBuilder.addOutput("TO_ADDRESS2", coinstackclient.Math.toSatoshi("0.03"));
txBuilder.setInput("MY_WALLET_ADDRESS");
txBuilder.buildTransaction(function(err, tx) {
    tx.sign("MY_PRIVATE_KEY_WIF")
    var rawTx = tx.serialize()

    // send transaction
    coinstackclient.sendTransaction(rawTx, function(err) {
        if (null != err) {
            console.log("failed to send tx");
        }
    );
});
Meteor
// server
// create transaction
var txBuilder = coinstackclient.createTransactionBuilder();
txBuilder.addOutput("TO_ADDRESS1", coinstackclient.Math.toSatoshi("0.01"));
txBuilder.addOutput("TO_ADDRESS2", coinstackclient.Math.toSatoshi("0.03"));
txBuilder.setInput("MY_WALLET_ADDRESS");
var tx = coinstackclient.buildTransactionSync(txBuilder);
tx.sign("MY_PRIVATE_KEY_WIF");
var rawTx = tx.serialize();

// send transaction
try {
    coinstackclient.sendTransactionSync(rawTx);
} catch (e) {
    console.log("failed to send tx");
}
// client
// create transaction
var txBuilder = coinstackclient.createTransactionBuilder();
txBuilder.addOutput("TO_ADDRESS1", coinstackclient.Math.toSatoshi("0.01"));
txBuilder.addOutput("TO_ADDRESS2", coinstackclient.Math.toSatoshi("0.03"));
txBuilder.setInput("MY_WALLET_ADDRESS");
txBuilder.buildTransaction(function(err, tx) {
    tx.sign("MY_PRIVATE_KEY_WIF");
    var rawTx = tx.serialize();

    // send transaction
    coinstackclient.sendTransaction(rawTx, function(err) {
        if (null != err) {
            console.log("failed to send tx");
        }
    );
});

4. Notification

You can notify any change from the Blockchain. (Now available only Java SDK)

Streamed

When a change transpires in Blockchain, it gets continuously through the connection-oriented transport. (active)

Event hook

A change in Blockchain is received through the event hook. (passive) This method supports HTTP endpoint and Amazon SNS integration. The content is sent as JSON type.

4.1. Create

Create a Subscription object to notify a change.

Java
Subscription newSubscription = new Subscription(
        "YOUR_WALLET_ADDRESS", "YOUR_EXTERNAL_SERVICE_ID");
String subscriptionId = coinStackClient.addSubscription(newSubscription);

4.2. Check

Check all Subscriptions list.

Java
// list previous subscriptions
Subscription[] subscriptions = coinStackClient.listSubscriptions();
System.out.println("listing subscriptions");
for (Subscription subscription : subscriptions) {
    System.out.println(subscription.getId());
    coinStackClient.deleteSubscription(subscription.getId());
}

4.3. Delete

Delete a Subscription object.

Java
coinStackClient.deleteSubscription("YOUR_EXTERNAL_SERVICE_ID");

results matching ""

    No results matching ""