Armory is an Open-Source wallet with cold storage and multi-signature support Armory was build in Python and parts of the wallet are in C++. The example code that Armory provides is outdated, limited needs to be updated to be useful; In this tutorial we show you some examples how to use it.
Installing Armory
If you do not have Armory Secure Bitcoin wallet installed, do this tutorial : https://bitcoinarmory.com/building-from-source/
ArmoryEngine
The main library to use is armoryengine. This library contains loads of bitcoin related functions. You can use Python 2.7 to communicate with this library. The library has several packages which we will discuss below.
ArmoryEngine PyBtcWallet
This package is able to interact with wallet files. Create this script:
1
2
3
4
5
6
7
8
9
10
|
#! /usr/bin/python
from armoryengine import *
from armoryengine.PyBtcWallet import PyBtcWallet
from armoryengine.PyBtcAddress import PyBtcAddress
from time import time, sleep
import sys
wlt = PyBtcWallet().readWalletFile( 'extras/test/FakeWallet123.wallet' )
print wlt.getNextUnusedAddress().getAddrStr()
print wlt.getWalletVersion()
|
And save it as example.py inside /BitcoinArmory/. You can now execute it with:
1
|
python example.py
|
which should output the address of that wallet. The package has many more functions which you can see in the file /armoryengine/PyBtcWallet.py
ArmoryEngine PyBtcAddress
This package contains a lot of neat functions for working generating keys.
Generate a bitcoin address from a public key:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#! /usr/bin/python
# generate bitcoin address from public key, talkera.org
from armoryengine import *
from armoryengine.PyBtcWallet import PyBtcWallet
from armoryengine.PyBtcAddress import PyBtcAddress
from armoryengine.ArmoryUtils import *
from time import time, sleep
from CppBlockUtils import BtcWallet as CppBtcWallet
import sys
satoshiPubKey = hex_to_binary('04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f')
AddrA = PyBtcAddress().createFromPublicKey(satoshiPubKey)
print AddrA.getAddrStr()
|
Generate a bitcoin address from a private key:
1
2
3
4
5
6
7
8
9
10
11
12
|
#! /usr/bin/python
# generate bitcoin address from private key, talkera.org
from armoryengine import *
from armoryengine.PyBtcWallet import PyBtcWallet
from armoryengine.PyBtcAddress import PyBtcAddress
from armoryengine.ArmoryUtils import *
from time import time, sleep
from CppBlockUtils import BtcWallet as CppBtcWallet
import sys
AddrA = PyBtcAddress().createFromPrivateKey(hex_to_int('bb'*32))
print AddrA.getAddrStr()
|
Generate a bitcoin address from a brainwallet key:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#! /usr/bin/python
# generate bitcoin address from private key, talkera.org
from armoryengine import *
from armoryengine.PyBtcWallet import PyBtcWallet
from armoryengine.PyBtcAddress import PyBtcAddress
from armoryengine.ArmoryUtils import *
from time import time, sleep
from CppBlockUtils import BtcWallet as CppBtcWallet
import sys
brain = 'Man made it to the moon,, and decided it stinked like yellow cheeeese.'
priv = sha256(brain)
AddrA = PyBtcAddress().createFromPrivateKey(priv)
print AddrA.getAddrStr()
|
this will output the bitcoin address 1CeU9ugjwfsnzrhqjKy1HUBzXCCXVC76m1.
ArmoryEngine Block
This package is used to interact with the blockchain. Armory is not a lite wallet, it downloads the entire blockchain to the disk. To print the genisis block use this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#! /usr/bin/python
# get the genisis block from the blockchain database, talkera.org
from armoryengine import *
from armoryengine.PyBtcWallet import PyBtcWallet
from armoryengine.PyBtcAddress import PyBtcAddress
from armoryengine.ArmoryUtils import *
from armoryengine.Block import *
from time import time, sleep
from CppBlockUtils import BlockHeader as CppBlockHeader
from CppBlockUtils import Tx as CppTx
from CppBlockUtils import TxIn as CppTxIn
from CppBlockUtils import TxOut as CppTxOut
from CppBlockUtils import BtcWallet as CppBtcWallet
import sys
blkfile = open('/home/YOURUSERNAME/.bitcoin/blocks/blk00000.dat','r')
blkfile.seek(8,0)
genBlock = PyBlock().unserialize(blkfile.read(80 + 1 + 285))
blkfile.close()
print 'Genesis block header:'
genBlock.blockHeader.pprint()
print 'Genesis block tx:'
genBlock.blockData.txList[0].pprint()
|
Remember to put the path to the file correctly. The output should be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
Genesis block header:
BlockHeader:
Version: 1
ThisHash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f (BE)
PrevBlock: 0000000000000000000000000000000000000000000000000000000000000000 (BE)
MerkRoot: 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b (BE)
Timestamp: 1231006505
Difficulty: 1.0 (ffff001d)
Nonce: 2083236893
Genesis block tx:
Transaction:
TxHash: 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b (BE)
Version: 1
nInputs: 1
nOutputs: 1
LockTime: 0
Inputs:
PyTxIn:
PrevTxHash: 0000000000000000000000000000000000000000000000000000000000000000 (BE)
TxOutIndex: 4294967295
Script: (04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368)
Sender: UNKNOWN>
Seq: 4294967295
Outputs:
TxOut:
Value: 5000000000 (50.0)
Script: PubKey(1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa) OP_CHECKSIG
|
Get latest block hash from a file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
#! /usr/bin/python
# get latest block hash from file, talkera.org
from armoryengine import *
from armoryengine.PyBtcWallet import PyBtcWallet
from armoryengine.PyBtcAddress import PyBtcAddress
from armoryengine.ArmoryUtils import *
from armoryengine.Block import *
from time import time, sleep
from CppBlockUtils import BlockHeader as CppBlockHeader
from CppBlockUtils import Tx as CppTx
from CppBlockUtils import TxIn as CppTxIn
from CppBlockUtils import TxOut as CppTxOut
from CppBlockUtils import BtcWallet as CppBtcWallet
import sys
import os
BLOCK_SIZE_LENGTH = 4
MAGIC_NUMBER_LENGTH = 4
HEADER_LENGTH = 80
def getNextBlockHash(f):
fileOffset = f.tell()
f.seek(MAGIC_NUMBER_LENGTH, 1)
blkSize = binary_to_int(f.read(BLOCK_SIZE_LENGTH), LITTLEENDIAN)
result = None
if blkSize > 0:
blkString = f.read(blkSize)
blkHdrBinary = blkString[:HEADER_LENGTH]
result = sha256(sha256(blkHdrBinary))
else:
f.seek(0,2)
return result
def getLastBlockHash(blkFile):
result = None
with open(blkFile, 'rb') as f:
fSize = os.path.getsize(blkfile)
while f.tell() fSize:
blockHash = getNextBlockHash(f)
if blockHash != None:
result = blockHash
return result
blkfile = '/home/YOURUSERNAME/.bitcoin/blocks/blk00000.dat'
print binary_to_hex(getLastBlockHash(blkfile))
|
ArmoryEngine More
There is more stuff inside the library, much more than would fit into a single post. Depending on the interest in this post (feel free to comment), we will add more.