Discover more from DeFi Education
Signing Transactions with an Offline Computer
Level 3 - Virgin DeFi Analyst
Today we have some useful information on setting up a separate offline computer to sign crypto transactions.
Many crypto power-users have hot wallets for interacting with DeFi and storing smaller amounts of capital, and offline “Vault” addresses which are rarely used and store large value.
This post is for you if:
you are restoring from a 12 or 24 word seed phrase (e.g. from a physical backup)
you want decent security without using a hardware wallet
you’re interested in different ways of securing crypto transactions
What Is An Airgapped Computer?
An offline computer - also known as an airgapped computer - is a computer which is physically isolated from any network or Internet connection, making it much more secure against cyber threats.
We don’t recommend using this process for day-to-day / hot wallet transactions (unless using QubesOS, a special security-focused operating system which makes this process much more convenient).
But. One of our writers followed this process earlier this week when transferring coins held in a long term cold storage “Vault” to a Gnosis Safe multisig.
This process is also good for safely restoring a seed phrase from a physical backup, especially if you don’t have a hardware wallet handy.
What About Hardware Wallets?
Autist note: For some users and threat models, this airgapped computer can be used (carefully) as a replacement for a hardware wallet. The offline PC functions as the isolated computing unit which stores the private key. A PC can be a ARM-based System-on-a-Chip like a Raspberry Pi, costing under $100 and the size of a cigarette carton. Combined with a battle tested open source Linux OS like Debian, this is a realistic alternative to a Ledger or Trezor. Hardware wallets can only be used for crypto and therefore identifies the user as self-custodying cryptoassets. In some circumstances this can expose people to ‘wrench attacks’ / ‘rubber-hose cryptanalysis’. If you prefer to use a hardware wallet but don’t already own one (and a spare!), see our guide to hardware wallets here.
You will need:
two computers (or a computer running QubesOS)
a USB drive to transfer files between computers
knowledge of how to verify software downloads
The Online Machine
Install GPG (Gnu Privacy Guard) and Python (search the web for instructions on how to do this on your operating system). Mac and Linux is easy with brew, apt, etc. Windows you can search Git for windows to get a terminal, and use the chocolatey package manager to install the other apps.
The Offline Machine
No special requirements, just needs a web browser.
Verifying Software Downloads
Autist note: if you already know how to GPG verify software downloads, skip this section
You must *always* verify that crypto-related software you download isn’t malicious. The advantage of a browser plugin like Metamask is that the browers’ app store (in theory) does this for you. But. That takes the control away from the user. We recommend maintaining your own copy of important pieces of crypto software (all versions you install) so you can revert back to a known good copy if there is a bug in future versions.
GPG (GNU Privacy Guard) is an encryption tool that allows you to verify the authenticity of a file by checking its digital signature. Here's how you can verify a GPG signature from a downloaded file:
Download the signature file: The signature file should have a .asc or .sig extension, and is typically available on the same website where you download the file.
Import the signer's public key: In order to verify the signature, you need to import the public key of the person who signed the file. You can do this using the following command in your terminal:
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys <key-id>
Where <key-id> is the key ID of the signer. You can find the key ID from the website where you download the file.
Verify the signature: Once you have the signer's public key, you can verify the signature using the following command in your Downloads folder:
gpg --verify *sig
You will receive output, either a GOOD signature or a BAD signature. If GOOD, continue. If BAD, you must delete the file, but be aware the most likely problem was a corrupted / incomplete download rather than a malicious actor.
Bitcoin Split Wallet Options
Light Client | Electrum (User-friendly Option)
Electrum is a fast, secure, and easy-to-use Bitcoin client that supports split signing and offline transactions. Electrum was created in 2011 and is open source and cross platform (Windows, Mac, Linux).
Using Electrum doesn’t require advanced technical skills or the resources to run a full node.
Install Electrum: First, you need to download and install Electrum on both devices, one for the offline signing and one for the online transaction broadcasting. Important: GPG verify the download!
Import Wallet: On the offline device, import your seed to Electrum.
Export the public key: On the offline device, export the public key (XPUB). After creating the wallet, go to Wallet -> Information. The Master Public Key of your wallet is the string shown in this popup window. Transfer that key to your online machine. (you could save a text file to USB drive)
Import the public key: On your online machine, open up Electrum and select File -> New/Restore. Enter a name for the wallet and select “Standard wallet”. Select “Use public or private keys”. Paste your master public key in the box.
Create a new offline transaction: Go to the “send” tab on your online watching-only wallet, input the transaction data and press “Preview”. Press “save” and save the transaction file somewhere on your computer. Close the window and transfer the transaction file to your offline machine (e.g. with a USB drive).
Sign the transaction: On your offline wallet, select Tools -> Load transaction -> From file in the menu and select the transaction file created in the previous step. Press “sign”. Once the transaction is signed, the Transaction ID appears in its designated field. This will create a signed transaction, which is a piece of data that includes all the necessary information to broadcast the transaction to the Bitcoin network.
Export the signed transaction: Press save, store the file somewhere on your offline computer, and transfer it back to your online machine (e.g. via USB).
Broadcast the transaction: On your online machine, select Tools -> Load transaction -> From File from the menu. Select the signed transaction file. In the window that opens up, press “broadcast”. The transaction will be broadcasted over the Bitcoin network.
Full Node | Bitcoin Armory (Turbo Autist Option)
Armory is a secure and full-featured Bitcoin client written in Python and which provides advanced features for managing Bitcoin transactions and private keys. This was one of the first wallets we used which supported multisig on Bitcoin.
Armory requires the user to run a Full Node using the official Bitcoin Core client. There are video tutorials available.
Autist note: use a high performance machine (recent i5 or 8th gen i7 or newer, 8GB of free RAM, very fast SSD - NVME preferred) to avoid issues with performance. If you don’t keep your Bitcoin Core software running continuously, you’ll need to re-sync each time you start the app before you can make any transactions. You’ll need nearly 1T free disk space.
Here's how to set up Bitcoin Armory for split signing and offline transactions:
Install Bitcoin Armory: First, you need to download and install Bitcoin Armory on both devices, one for the offline signing and one for the online transaction broadcasting. Important: GPG verify the download!
Create a new wallet: On the offline device, create a new wallet in Armory. Make sure to create a backup of the wallet seed.
Export the public key: On the offline device, export the public key of the wallet you just created. This can be done from the Armory wallet interface by selecting "Export Key Lists" and then "Public Key" for the specific wallet.
Import the public key: On the online device, import the public key you just exported. This can be done from the Armory wallet interface by selecting "Import Key Lists" and then "Public Key".
Create a new offline transaction: On the offline device, create a new transaction using the Armory wallet interface. Make sure to specify the correct recipient address and the desired amount.
Sign the transaction: On the offline device, sign the transaction using the Armory wallet interface. This will create a signed transaction, which is a piece of data that includes all the necessary information to broadcast the transaction to the Bitcoin network.
Export the signed transaction: On the offline device, export the signed transaction. This can be done from the Armory wallet interface by selecting "Export Key Lists" and then "Signed Transaction".
Broadcast the transaction: On the online device, broadcast the signed transaction to the Bitcoin network. This can be done from the Armory wallet interface by selecting "Broadcast" and then uploading the signed transaction file you exported.
Ethereum Split Wallet
We have only used MyEtherWallet (MEW), one of the original Ethereum wallets launched in 2015, for split signing on Ethereum. We don’t write about what we haven’t tested, and we prefer Lindy software for obvious reasons. If there’s another Ethereum wallet you like which supports split signing, please let us know in the comments.
By following these steps you’ll get experience running a simple Python script and using LlamaNodes, the free alternative to Metamask/Infura RPC. This is good for privacy, especially if you broadcast from behind a VPN or using the Tor network.
Caution: Etherum transactions are more complex to create by hand (there is no simple ‘watching only’ interface to do it for you). Gas price, gas limit, and nonce needs to be set by hand. And if you’re sending a new or relatively unknown ERC-20 token, or an NFT, or trying to interact with a smart contract - this method isn’t for you. This is best for sending plain ETH.
If you’ve decided you want to get a look under the hood of how Ethereum transactions are built, let’s dig in. Another good reason to do this is transferring your hoard of ETH from an EOA, to a Gnosis safe multisig, perhaps with your executors/beneficiaries set up as multi-signers.
Here’s the process:
Download and Install MyEtherWallet: You need to have a working installation of MyEtherWallet on both devices, one for online access and one for offline signing.
Import wallet: On the offline device, open MyEtherWallet from USB drive by double clicking the index.html file. Select software / mnemonic phrase. Enter your Seed Phrase and click Next. You will be prompted to select your Address and Network. Usually this will be Ethereum mainnnet but you may be interacting with assets on other chains.
Create a new offline transaction: the Send Offline feature will be presented by default. Here you can enter the token name (ETH or ERC-20 token), the amount to send, and the “to address”.
Find your gas limit: For sending ETH, the default limit of 21,000 is correct. For an ERC-20 transfer, most contracts will complete under 200,000 gas (very rare exceptions for non-standard tokens - simulate or check documentation if this is a concern). Remember that unused gas is refunded, this is just a *limit*.
Calculate your nonce: The nonce (number used only once) counts the number of transactions your wallet has sent. You need to add 1 to this number for the next transaction. You can either look this up on Etherscan or in Python:
Etherscan: look up your sending address, click on the most recent transaction, “click to see more” and look for the nonce number on the other attributes line:
You need to add 1 to this number (54) to get the nonce for the next transaction. If this wallet has never made a transaction, set nonce to zero.
Python: run this code from an Internet connected PC, replace 0xYourAddressHere with the sending address
Set the Gas price: You’ll need to check Etherscan on the online device to find the current gas price, then set according to transaction urgency. The units are in wei so you’ll need to multiply by 10**9 to get Gwei. For example 35 Gwei should be entered as 35000000000 (add nine zeros). You can refer to these online calculators to help convert Ethereum units.
Sign the transaction: Click Generate Transaction box on the offline device to sign the transaction using the MyEtherWallet interface. This will create a signed transaction, which is a piece of data that includes all the necessary information to broadcast the transaction to the Ethereum network.
Export the signed transaction: On the offline device, export the signed transaction. For example you can copy and paste into a notepad file and then save the file to a USB device. Take the USB device to your online machine.
Broadcast the transaction: On the online device, broadcast the signed transaction to the Ethereum network. We’re going to use a Python script and Llama Nodes. Paste the transaction you generated into this Python code where 0xYourSignedTransactionHere appears:
The successful output is a transaction hash which you can look up on Etherscan. If something has gone wrong, you’ll receive an error message.
You may need to install the web3 package for Python, usually by running the
pip3 install web3 (or
pip install web3) command.
A note on the Python snippets: Substack is adding line breaks where they shouldn’t exist, so the full code is on Github.
And that’s a wrap! We hope you found this more technical post useful. It’s a free post so if you enjoyed it please give it a share and consider becoming a paid subscriber.
Until next time, anon..
Disclaimer: None of this is to be deemed legal or financial advice of any kind. These are opinions from an anonymous group of cartoon animals with Wall Street and Software backgrounds.