What’s New in Blockchain?

Piero Sanchez, WRSA
Akira Toma, WRSA

What is a blockchain?

No standard definition for a blockchain.

We have to adapt to the different kinds of architectures of each blockchain.

General idea of a blockchain is a decentralized (or sometimes distributed) append-only ledger ruled by a consensus algorithm.

Common architecture involves sets of transactions included in blocks that are cryptographically linked in sequential order.

Blockchain functions

Reading functions

BlockchainData

BlockchainBlockData

BlockchainTransactionData

BlockchainAddressData

Writing functions

BlockchainTransaction

BlockchainTransactionSign

BlockchainTransactionSubmit

Supported blockchains

Bitcoin

Ethereum

ARK ← New!

ARK - Wolfram partnership

ARK is a Delegated Proof of Stake blockchain.

ARK offers tools for blockchain creation.

Every address can vote for a delegate by staking their balance. Only the 51 delegates with the most votes are allowed to forge a block.

Forging is equivalent to mining in Bitcoin, the delegate that forges gets a reward plus the sum of fees from all contained transactions.

(HyperlinkURL["https://ark.io/", https://ark.io/])

Now supporting connection from WL to the ARK Mainnet and Devnet networks.

Now supporting reading and writing functions.

(HyperlinkURL["https://blog.ark.io/ark-partners-with-wolfram-blockchain-labs-556811108e16", https://blog.ark.io/ark-partners-with-wolfram-blockchain-labs-556811108e16])

Creating a simple transaction

Steps for sending ARK from an existing address to a newly created address.

Create a transaction

Use a new address as the recipient.

newAddress="AUrcKYbn62nqnBQwmujRiiiYHHfAj7BBKz";

Import an existing address and use it as the sender.

personalKeys=Import[NotebookDirectory[]<>"oldKeys.wl"]

\[LeftAssociation]"PrivateKey"->PrivateKey[],"PublicKey"->PublicKey[],"Address"->"AH9oeMA5pfyozjUzJkisKrLhiKghRmLnrV"\[RightAssociation]

personalAddress=personalKeys["Address"]

This address must have enough balance to pay for the amount and fee

oldBalance=BlockchainAddressData[personalAddress,"Balance",BlockchainBase->"ARK"]

Decide on the fee and the amount to transfer

fee=Quantity[3000000,"Arktoshis"]

amount=Quantity[0.05,"Arks"]

Create the transaction object locally. We can add a small message using “VendorField”.

create=BlockchainTransaction[<|"BlockchainBase"->"ARK","Recipient"->newAddress,"Fee"->fee,"Amount"->amount,"VendorField"->"Sent from WTC 2019!"|>]

Sign the transaction

Sign the transaction object locally with the sender’s PrivateKey object.

personalKeys["PrivateKey"]

PrivateKey[]

sign=BlockchainTransactionSign[create,PrivateKey[]]

The “SenderPublicKey” and “Signature” fields get added to the transaction object.

sign["SenderPublicKey"]

sign["Signature"]

Submit the transaction

Send the transaction object to the blockchain

submit=BlockchainTransactionSubmit[sign]

The “TransactionID” gets added to the transaction object.

newTransactionID=submit["TransactionID"]

We should now wait for our transaction to be added to a new block and for that block to be forged by a delegate.

Reading the blockchain

Blockchain

Get some general information about the blockchain.

BlockchainData[BlockchainBase->"ARK"]//Dataset

BlockchainData["FeeStatistics",BlockchainBase->"ARK"]//Dataset

fee=Quantity[3000000,"Arktoshis"]

Because this is a supported Quantity in WL, we can easily make conversions.

1 Arktoshi is the minimum unit of currency for ARK.

1 ARK or 1 Ѧ is the main coin worth (10^8)Arktoshis.

CurrencyConvert[N[fee],"Arks"]

CurrencyConvert[N[fee],"USDollars"]

Transaction

Review the newly created transaction.

BlockchainTransactionData[newTransactionID,BlockchainBase->"ARK"]//Dataset

newBlockID=BlockchainTransactionData[newTransactionID,"BlockID",BlockchainBase->"ARK"]

Block

Review the block that contains the new transaction.

BlockchainBlockData[newBlockID,BlockchainBase->"ARK"]//Dataset

The “Generator” field contains the information of the delegate who forged this block.

BlockchainBlockData[newBlockID,"Generator",BlockchainBase->"ARK"]//Dataset

delegate=BlockchainBlockData[newBlockID,"Generator",BlockchainBase->"ARK"]["Username"]

This delegate got a static reward for forging plus the fees of all contained transactions. We can see this under the “Forged” field.

BlockchainBlockData[newBlockID,"Forged",BlockchainBase->"ARK"]//Dataset

Address

The information on the new address is now updated

BlockchainAddressData[newAddress,BlockchainBase->"ARK"]//Dataset

BlockchainAddressData[newAddress,"TransactionList",BlockchainBase->"ARK"]//Dataset

Compare the old and new balance of the sender address

oldBalance

newBalance=BlockchainAddressData[personalAddress,"Balance",BlockchainBase->"ARK"]

newBalance+amount+fee==oldBalance

We can look for more information about the delegate who forged our block.

BlockchainAddressData[delegate,BlockchainBase->"ARK"]//Dataset

Which delegate this address voted for

BlockchainAddressData[delegate,"VotedFor",BlockchainBase->"ARK"]//Dataset

Who voted for this delegate

BlockchainAddressData[delegate,"Voters",BlockchainBase->"ARK"]//Shallow

Information about this delegate’s revenue

BlockchainAddressData[delegate,"Forged",BlockchainBase->"ARK"]//Dataset

What is an oracle?

Simple transactions

Transactions with conditions

Turing-complete languages to support more complex conditions

Oracles as a way to get data from the real world

Wolfram|Alpha is the largest computational engine in the world used by various virtual assistants (e.g. Siri, Alexa, etc)

It seems natural to use Wolfram|Alpha as the main provider of computational facts for smart contracts

Architecture

Wolfram Oracle

Currently, testing on Ropsten testnet network of the Ethereum protocol. Soon to be released.

Uses natural language input to interact with the Wolfram knowledgebase, removing the need to use messy and poorly documented APIs.

There are two ways to interact with the oracle: directly copy and paste Solidity code to your smart contract or deploy it using Wolfram Language.

Deploying user contract

Initialization

Initialize private key:

privKey=PrivateKey[];

Derive associated address:

address=BlockchainKeyEncode[privKey,"Address",BlockchainBase->"Ethereum"]

Define the parameters for the transactions:

contractBalance=Quantity[1,"Gwei"]

txcount=BlockchainAddressData[address,"TransactionCount",BlockchainBase->{"Ethereum", "Testnet"}]

txcount2=txcount+1

gasprice=BlockchainData["HighestGasPrice",BlockchainBase->{"Ethereum", "Testnet"}]

Solidity template

code="pragma solidity ^0.4.24;

contract WolframAlphaQuery{

  uint256 public alphaResponse;
  address public owner;

  modifier onlyOwner {
    require(msg.sender == owner, 'Only owner can call this function.');
    _;
  }

  constructor() public payable {
    owner = msg.sender;
  }

  function queryAlpha(uint256 _amount) public onlyOwner {
    if(!address(0x1b22E02d1665CEE499E83D52Bd8f7C1914cc6E7b).call.value(_amount)(abi.encodeWithSignature(
      'callWolframAlpha(address,string,string)',
      address(this),
      'callback',
      'RandomInteger[{10, 50}]'))
    ){
      revert('Amount sent is too low.');
    }
  }

  function callback(uint256 _response) public {
    alphaResponse = _response;
  }

}";

Contract deployment

Create transaction:

tx=BlockchainTransaction[<|"BlockchainBase"->{"Ethereum","Testnet"},"TransactionCount"->txcount,"Contract"-><|"SourceCode"->code|>,"GasPrice"->gasprice,"Amount"->contractBalance|>]

Sign transaction:

txSigned=BlockchainTransactionSign[tx,privKey]

Submit transaction:

txSent=BlockchainTransactionSubmit[txSigned]

Get the contract’s address:

contractAddress=BlockchainTransactionData[txSent["TransactionID"],"ContractAddress",BlockchainBase->{"Ethereum", "Testnet"}]

Get the initial value of the state variable:

BlockchainContractValue[contractAddress,Typed["alphaResponse","uint256"],BlockchainBase->{"Ethereum", "Testnet"}]

Query Alpha

Create query transaction:

tx2=BlockchainTransaction[<|"BlockchainBase"->{"Ethereum","Testnet"},"TransactionCount"->txcount2,"Address"->contractAddress,"GasPrice"->gasprice,"FunctionCall"-><|"Function"->Typed["queryAlpha",{"uint256"}->{}],"Inputs"->5000,"Sender"->address|>|>]

Sign query transaction:

txSigned2=BlockchainTransactionSign[tx2,privKey]

Submit query transaction:

txSent2=BlockchainTransactionSubmit[txSigned2]

Verify the update of the state variable:

BlockchainContractValue[contractAddress,Typed["alphaResponse","uint256"],BlockchainBase->{"Ethereum", "Testnet"}]