HowTo VeChain Blockchain — Part 5

MiRei
3 min readJul 23, 2020

Python-powered VET transfers

(Links to all parts at the bottom)

So, after the basics in VeChain blockchain transfers it’s now time to upgrade the script a little. Until now everything was pretty manual but that will change. To to that, we need to load two more python modules:

from random import randint
import json

With these, we can auto-update BlockRef and Nonce (described in Part 2). We will also put the transaction body and the clause part into a more manageable format.

Update BlockRef:
As said in Part 2 the BlockRef refers to the first 18 charakters of the best (newest) block. Having access to a VeChain Node, we can always take a look at the best block like this: https://testnet.veblocks.net/blocks/best
There you can see all relevant information about the newest block on the blockchain. We are interested in the “id” value.

With “requests” from Part 3 and “json”, python can do something like this:

_node_url = 'https://testnet.veblocks.net'# Get infos of best block
BlockInfos = requests.get(_node_url + '/blocks/best')
# set BlockRef to best block
_BlockRef = BlockInfos.json()['id'][0:18]

This will get the information from the best block, take the “id” value and use the characters 0 to 18 of it. Done.

Update Nonce:
Thats easy, just generate a random number between 10000000 and 99999999 so it always has 8 digits:

_Nonce = randint(10000000, 99999999)

Modify transaction body:
Until now, we used a written body but we can also but this body inside some variables:

body = {}
body['chainTag'] = _ChainTag
body['blockRef'] = _BlockRef
body['expiration'] = 720
body['clauses'] = _transaction_clauses
body['gasPriceCoef'] = 0
body['gas'] = 85000 # 5000 + (5 * 16000)
body['dependsOn'] = None
body['nonce'] = _Nonce

Modify clauses part of the body:
In the body above the “clauses” part is a variable too and it is defined like this.

_transaction_clauses = [
{'to': '0x0000000000000000000000000000000000000000', 'value': 1000000000000000000, 'data': '0x'},
{'to': '0x0000000000000000000000000000000000000009', 'value': 1000000000000000000, 'data': '0x'},
{'to': '0x0000000000000000000000000000000000000010', 'value': 1000000000000000000, 'data': '0x'},
{'to': '0x0000000000000000000000000000000000000011', 'value': 1000000000000000000, 'data': '0x'},
{'to': '0x0000000000000000000000000000000000000012', 'value': 1000000000000000000, 'data': '0x'}
]

When viewed on github or as a picture from the editor, this looks very simple. All we need to take care of is add/edit/delete one line of readable code to expand/shrink a multiclause transaction!

Snipplet of a multi-clause-transaction on VeChain testnet.

So this is the script 5_python_powered_vet-transfers.py as whole

from thor_devkit import cry, transaction
import requests
from random import randint
import json
# Sender wallet information
# mnemonic phrase: twenty, jelly, around, appear, approve, version, general, bright, crumble, all, master, sail
# address: 0xbc1497fc775f5cbf42dfeca44d97efaba79462b7
# private key: 61faba91ef7516969e885d197f59feeb2007ea2c6057908d1696d6f056ca69d4
_privatekey = '61faba91ef7516969e885d197f59feeb2007ea2c6057908d1696d6f056ca69d4'
_node_url = 'https://testnet.veblocks.net'
_ChainTag = 39
# Get infos of best block
BlockInfos = requests.get(_node_url + '/blocks/best')
# set BlockRef to best block
_BlockRef = BlockInfos.json()['id'][0:18]
# generate random noce
_Nonce = randint(10000000, 99999999)
### create list of clauses
_transaction_clauses = [
{'to': '0x0000000000000000000000000000000000000000', 'value': 1000000000000000000, 'data': '0x'},
{'to': '0x0000000000000000000000000000000000000009', 'value': 1000000000000000000, 'data': '0x'},
{'to': '0x0000000000000000000000000000000000000010', 'value': 1000000000000000000, 'data': '0x'},
{'to': '0x0000000000000000000000000000000000000011', 'value': 000000000000000000, 'data': '0x'},
{'to': '0x0000000000000000000000000000000000000012', 'value': 1000000000000000000, 'data': '0x'}
]
### Build transactionbody = {}
body['chainTag'] = _ChainTag
body['blockRef'] = _BlockRef
body['expiration'] = 720
body['clauses'] = _transaction_clauses
body['gasPriceCoef'] = 0
body['gas'] = 85000 # 5000 + (5 * 16000)
body['dependsOn'] = None
body['nonce'] = _Nonce
# Construct an unsigned transaction.
tx = transaction.Transaction(body)
# Sign the transaction with a private key.
priv_key = bytes.fromhex(_privatekey)
message_hash = tx.get_signing_hash()
signature = cry.secp256k1.sign(message_hash, priv_key)
# Set the signature on the transaction.
tx.set_signature(signature)
print('Created a transaction from ' + tx.get_origin() + ' with TXID: ' + tx.get_id() + '.')
print('')
encoded_bytes = tx.encode()# pretty print the encoded bytes.
print('The transaction "0x' + encoded_bytes.hex() + '" will be send to the testnet node now.')
tx_headers = {'Content-Type': 'application/json', 'accept': 'application/json'}tx_data = {'raw': '0x' + encoded_bytes.hex()}send_transaction = requests.post(_node_url + '/transactions', json=tx_data, headers=tx_headers)print('Response from Server: ' + str(send_transaction.content))

This script can be repeated without manual modification, because BlockRef and Nonce are updated automatically and it will create transactions with 5 VET clauses.

Next step… gas calculation.

--

--