Professional Documents
Culture Documents
To avoid the problems associated with previously used GCC blockchain and to resume project
development decision to temporarily swap tokens to another, more stable cryptocurrency platform
was made. The choice of a new platform happened to be Ethereum which resulted in a need to create
a system which would allow GCC-holders to move their holdings from the current system to the new
one. This marked the start of development of the swap system.
2. Thought Process
2.1. Requirements
Successfully meeting those requirements meant implementation of a totally new token on Ethereum
platform was needed. That token had to follow ERC20 interface, but at the same time implement
custom staking solution that follows current staking logic. Additionally, a way to swap tokens between
two separate blockchains had to be prepared.
2.2. Solution
The solution to the problem came in a form of Oracle-lead swap from GCC Blockchain to Ethereum.
The process was designed to require the user to burn his tokens on the first blockchain while providing
a self-signed message containing his Ethereum address. After performing burn, a link, or rather proof
of burn is going to be added to Oracle contract deployed on Ethereum. Oracle is a public data provider
of all valid burns made on GCC blockchain. After injecting new record to Oracle system, it can be
consumed by ERC20 token itself and mint the amount proved to be burned on a new chain. Trustless
model is provided by auditable information and immutability not preventing to change that data and
possibility for users to do all the swap instructions manually if they do not trust convenience services
GCC is going to provide them in a form of swap webservice.
3. Implementation
3.1. Codebase
Repository: Purpose:
3.2. Deployment
Detailed information about deploying each of previously mentioned repositories has been provided
inside each one of them. This section focuses on composition of all of them into a working swap
system. To deploy everything correctly and in valid order:
A. Deploy GCC node using `gcc-service-docker` repository. Remember to deploy RPC Server
script as a workaround for connection problems too.
B. Deploy ETH node using `gcc-service-docker` repository. Use `geth` for public network and/or
`ganache` for private ones.
C. Deploy SQL service using `gcc-service-docker`.
D. Deploy all ETH contracts (ERC20 + Oracle) using migrations in `gcc-eth` service.
E. Deploy `gcc-service-swap-eth` service. Make sure to deploy `Account Controller` as well!
F. Deploy `gcc-service-swap-src` service.
G. Deploy `gcc-service-swap-controller` service.
3.3. High-Level Overview
When everything is deployed correctly, the high-level overview of the system will look as presented in
following diagram:
4. Making a Swap
1. (Optional) User sending his funds from his wallet to address that was generated for him by swap
controller
2. Swap controller (or User) making valid OP_RETURN transaction that burns tokens and
provides ETH address where user want to receive them on Ethereum
3. Swap controller injecting new Proof of Burn record into Oracle using addProof function.
4. Swap controller (or User) consuming freshly injected PoB and minting+airdropping appropriate
amount of tokens ETH address user provided during burn transaction.
The first step - which requires user to send his coins to our wallet is an optional one created for the
purpose of less technical people. It is possible of user omitting this step and starting directly from step
2. By executing OP_RETURN himself. Nevertheless, since cross-chain swap is complicated process, the
option with sending tokens to us should be the recommended one. Option to do swap directly without
our help should be marked as possible, but not-recommended.
The swap process with a little more detail can be seen in following diagram:
This diagram presents same flow as described in page before, but gives a little more coherent view
what goes where, and includes waiting instructions as well. Optional instructions are marked as 1.x.
Manual swap refers to swap in which user does not take advantage of optional step of sending his funds
to address which was generated for him by controller. There might be few reasons why user want to
skip that step, but the main one would be him not wanting losing control of his funds. This option should
be highly discouraged from users, since they may make a irrecoverable mistake and lose their funds.
To make a manual swap user has to create an OP_RETURN transaction from his wallet. That
OP_RETURN transaction needs to:
OP_RETURN 8644a28b7e5c7d4458f6ce22ecf8e40f2511904d2dd0
186a168644a28b7e5c7d4458f6ce22ecf8e40f2511904d2dd0
That RAW output can be understood as follows, by order:
- 0x18 - output is 24 byte long
- 0x6a - output is OP_RETURN type
- 0x16 - OP_RETURN data that follows is 22 byte long
- 0x8644 - custom protocol marker
- 0xa28b7e5c7d4458f6ce22ecf8e40f2511904d2dd0 - ETH address
At this point, it should be clear that making this kind of transaction manually can be difficult, so only
people that really knows what they do should try it. Generally speaking GCC blockchain has the same
interface for OP_RETURN as Bitcoin, so any instruction for Bitcoin is valid for GCC as well.
To create this transaction, it is recommended to use GCC full-node and its interface.
This section is explanation how to create manually OP_RETURN transaction for swap with usage of
GCC Node in a pseudo-code.
first_unspent = rpc.listunspent()[0]
txid = first_unspent['txid']
vout = first_unspent['vout']
input_amount = first_unspent['amount']
fee = Decimal("0.000001")
burn_amount = Decimal(AmountToBurn)
change_amount = input_amount - burn_amount - fee
Create transaction with receiver being zero-address of GCC blockchain. Zero-address is the valid
address that has been computed from invalid 0byte publickey. In GCC blockchain this is
“RwxQ3jUs2BjKhseNX1em4msn2GyVBjd1Lc”.
This code will create a standard transaction to zero-address with change being send to user’s
own address. Before sending it, a change to OP_RETURN needs to be made.
This is the most important part of creating OP_RETURN transaction. We take the raw code of
transaction created in previous step, and replace standard script of OP_DUP OP_HASH16 etc. with
an OP_RETURN script.
# Pattern to replace
# Represents length of script, then OP_DUP OP_HASH160,
# then length of hash, then 20 bytes of zeros, OP_EQUALVERIFY OP_CHECKSIG
standardScript = "1976a914000000000000000000000000000000000000000088ac"
prot = "8644"
data = ethAddressBytes // ex: a28b7e5c7d4458f6ce22ecf8e40f2511904d2dd0
data = prot + data
tx = tx.replace(standardScript, opreturnScript)
4.3.5. Sign It
tx = rpc.signrawtransaction(tx)['hex']
txid = rpc.sendtransaction(tx)
Done! Now just wait for your transaction to get into a block.
This document presented the high-level architecture of swap system, the logic of swap process and
presented information about two swap options being automatic and manual swap. System has been
created in a way that fulfils all the requirements given, and provides the easiest possible API to operate
with it. Automatic swap should be presented as default one, Manual should be presented as an option,
but highly discouraged to use, unless holder is really sure he knows what he is doing.