Skip to content

Getting Started

Yinghung.Poon edited this page Apr 19, 2022 · 5 revisions

This is an instruction for creating a wallet.

Initialize

Create an instance of MasterWalletManager

const std::string rootPath = "./Data";
const std::string netType = "MainNet" // can be "MainNet", "TestNet", "RegTest", "PrvNet"
const nlohmann::json config = R"({
              "BTC": { },
             	"ELA": { },
             	"IDChain": { },
             	"ETHSC": { "ChainID": 20, "NetworkID": 20 },
             	"ETHDID": { "ChainID": 20, "NetworkID": 20 },
             	"ETHHECO": { "ChainID": 128, "NetworkID": 128 }
             })"_json;
const std::string dataPath = "";//If empty, data of wallet will store in rootPath
try {
    MasterWalletManager *manager = new MasterWalletManager(rootPath, netType, config, dataPath);
    if (manager == nullptr) {
        // fail process
    }
} catch (...) {
	// exception process
}

Get created MasterWallet and SubWallet lists

try {
    std::vector<IMasterWallet *> masterWallets = manager->GetAllMasterWallets();
    if (masterWallets.size() == 0) {
        // see "Create master wallet" below
    } else {
        for (size_t i = 0; i < masterWallets.size(); ++i) {
            std::vector<ISubWallet *> subWallets = masterWallets[i]->GetAllSubWallets();
            // see transaction operation below
        }
    }
} catch (...) {
    // exception process
}

Create a master wallet

If "manager->GetAllMasterWallets()" return empty, then create one

  • Create standard HD master wallet with the mnemonic
const std::string walletID = "HDWalletID";
const std::string passphrase = "";
const std::string payPassword = "Pay_Password~123^456";
const bool singleAddress = false;
const std::string wordCount = 12;
try {
    const std::string mnemonic = manager->GenerateMnemonic("english", wordCount);
    IMasterWallet *masterWallet = manager->CreateMasterWallet(
        walletID, mnemonic, passphrase, payPassword, singleAddress);
} catch (...) {
    // exception process
}
  • Create 3/4 multi-sign master wallet with the mnemonic
// ...
const std::string mnemonic =
		"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
uint32_t m = 3;
time_t timestamp = 0; // deprecated
bool compatible = false; // if true, will compatible with web old multi-sign wallet. false: BIP45, true: BIP44
nlohmann::json coSigners = R"(["xpub6CLgvYFxzqHDJCWyGDCRQzc5cwCFp4HJ6QuVJsAZqURxmW9QKWQ7hVKzZEaHgCQWCq1aNtqmE4yQ63Yh7frXWUW3LfLuJWBtDtsndGyxAQg", "...", "..."])"_json;
try {
	// ...
    IMasterWallet *masterWallet = manager->CreateMultiSignMasterWallet(
        walletID, mnemonic, passphrase, payPassword, coSigners, m, false, timestamp);
} catch (...) {
    // exception process
}

Create a sub wallet

  • Get all supported sub wallet ID
// ...
try {
    std::vector<std::string> subWalletIDList = masterWallet->GetSupportedChains();
} catch (...) {
    // exception process
}
  • Create a sub wallet
try {
    ISubWallet *subWallet = masterWallet->CreateSubWallet(subWalletIDList[0]);
} catch (...) {
    // exception process
}

Create a normal transfer

  • Create a normal transfer asset transaction implemented in SubWallet
const std::string inputJson = "[
                {
                  "TxHash": "...", // string
                  "Index": 123, // int
                  "Address": "...", // string
                  "Amount": "100000000" // bigint string in SELA
                },
                ...
              ]";
const std::string outputJson = "[
                {
                  "Address": "...", // string
                  "Amount": "100000000" // bigint string in SELA
                },
                ...
              ]";
const std::string fee = "10000"; // 10000 SELA
const std::string memo = "Hello elastos";
try {
    nlohmann::json tx = subWallet->CreateTransaction(inputJson, outputJson, fee, memo);
} catch (...) {
    // exception process
}

Create a cross-chain transaction

  • Deposit 1 ELA to ID chain
// ...
uint8_t version = 0x01; // 0x00: old deposit tx, 0x01: new deposit tx
std::string inputJson = "...";
std::string sidechainID = "IDChain";
std::string amount = "100000000";//1 ela
std::string sideChainAddress = "...";
std::string lockAddress = "D...";
std::string fee = "10000";
std::string memo = "memo";
// ...
try {
	IMainchainSubWallet *mcSubWallet = dynamic_cast<IMainchainSubWallet *>(subWallet);
    if (nullptr == mcSubWallet) {
        // subWallet is not instance of IMainchainSubWallet
        // do something
    }
    nlohmann::json tx = mcSubWallet->CreateDepositTransaction(version, inputJson, sidechainID, amount, sideChainAddress, lockAddress, fee, memo);
} catch (...) {
    // exception process
}
  • Withdraw 1 ELA from ID chain
// ...
std::string inputJson = "...";
std::string amount = "100000000"//1 ela;
std::string mainChainAddress = "EYMVuGs1FscpgmghSzg243R6PzPiszrgj7";
std::string fee = "10000";
std::string memo = "memo";

try {
    ISidechainSubWallet *SideSubWallet = dynamic_cast<ISidechainSubWallet *>(subWallet);
    if (nullptr == SideSubWallet) {
        // subWallet is not instance of ISidechainSubWallet
    }
    nlohmann::json tx = SideSubWallet->CreateWithdrawTransaction(inputJson, amount, mainChainAddress, fee, memo);
} catch (...) {
    // exception process
}

Create Producer transaction

Create a register producer transaction

// ...
std::string pubKey = mainchainSubWallet->GetOwnerPublicKey();
std::string nodePubKey = "0296e28b9bced49e175de2d2ae0e6a03724da9d00241213c988eeb65583a14f0c9";
std::string nickName = "xxx";
std::string url = "xxx.com";
std::string ipAddress = "127.0.0.1:8080";
uint64_t location = 86;
std::string memo = "memo";

std::string inputJson = "...";

try {
    IMainchainSubWallet *mainchainSubWallet = dynamic_cast<IMainchainSubWallet *>(subWallet);
    if (mainchainSubWallet == nullptr) {
			//subWallet is not instance of IMainchainSubWallet
			return;
    }
    nlohmann::json payload = mainchainSubWallet->GenerateProducerPayload(pubKey, nodePubKey, nickName, url, ipAddress, location, payPasswd);
	
    nlohmann::json tx = mainchainSubWallet->CreateRegisterProducerTransaction(inputJson, payload, "500000010000", "10000", memo);
} catch (...) {
    // exception process
}
	

Create a update producer transaction

// ...
std::string pubKey = mainchainSubWallet->GetOwnerPublicKey();
std::string nodePubKey = mainchainSubWallet->GetPublicKey();
std::string nickName = "xxx";
std::string url = "xxx.com";
std::string ipAddress = "110.110.110.110";
uint64_t location = 86;
std::string memo = "memo";

std::string inputJson = "...";

try {
    IMainchainSubWallet *mainchainSubWallet = dynamic_cast<IMainchainSubWallet *>(subWallet)
    if (mainchainSubWallet == nullptr) {
		//subWallet is not instance of IMainchainSubWallet
       return;
    }
    nlohmann::json payload = mainchainSubWallet->GenerateProducerPayload(pubKey, nodePubKey, nickName, url, ipAddress,
							location, payPasswd);
	
    nlohmann::json tx = mainchainSubWallet->CreateUpdateProducerTransaction(inputJson, payload, "10000", memo);
} catch (...) {
	// exception process
}

Create a cancel producer transaction

// ...
std::string pubKey = mainchainSubWallet->GetOwnerPublicKey();
nlohmann::json payload = mainchainSubWallet->GenerateCancelProducerPayload(pubKey, payPasswd);
std::string memo = "memo";

std::string inputJson = "...";

try {
    IMainchainSubWallet *mainchainSubWallet = dynamic_cast<IMainchainSubWallet *>(subWallet);
    if (mainchainSubWallet == nullptr) {
		//subWallet is not instance of IMainchainSubWallet
		return;
    }
    nlohmann::json tx = mainchainSubWallet->CreateCancelProducerTransaction(inputJson, payload, "10000", memo);
} catch (...) {
	// exception process
}

Create a vote transaction to a producer

// ...
std::string inputJson = "...";
nlohmann::json voteContents = R"(
			  [
			    {
			      "Type":"CRC",
			      "Candidates":
			      {
			        "iYMVuGs1FscpgmghSzg243R6PzPiszrgj7": "100000000",
			        ...
			      }
			    },
			    {
			      "Type":"CRCProposal",
			      "Candidates":
			      {
			        "109780cf45c7a6178ad674ac647545b47b10c2c3e3b0020266d0707e5ca8af7c": "100000000",
			        ...
			      }
			    },
			    {
			      "Type": "CRCImpeachment",
			      "Candidates":
			      {
			        "innnNZJLqmJ8uKfVHKFxhdqVtvipNHzmZs": "100000000",
			        ...
			      }
			    },
			    {
			      "Type":"Delegate",
			      "Candidates":
			      {
			        "031f7a5a6bf3b2450cd9da4048d00a8ef1cb4912b5057535f65f3cc0e0c36f13b4": "100000000",
			        ...
			      }
			    }
			  ])"_json;
std::string memo = "memo";

try {
    IMainchainSubWallet *mainchainSubWallet = dynamic_cast<IMainchainSubWallet *>(subWallet);
    if (mainchainSubWallet == nullptr) {
		//subWallet is not instance of IMainchainSubWallet
		return;
    }
	
    nlohmann::json tx = mainchainSubWallet->CreateVoteProducerTransaction(inputJson, voteContents, "10000", memo);
} catch (...) {
    // exception process
}

Create a retrieve transaction

// ...
std::string inputJson = "...";
std::string memo = "memo";
std::string amount = "5000000000";
try {
    IMainchainSubWallet *mainchainSubWallet = dynamic_cast<IMainchainSubWallet *>(subWallet);
    if (mainchainSubWallet == nullptr) {
		//subWallet is not instance of IMainchainSubWallet
		return;
    }
    nlohmann::json tx = mainchainSubWallet->CreateRetrieveDepositTransaction(inputJson, amount, "10000", memo);
} catch (...) {
    // exception proces
}

Sign transaction

  • Sign tx
// ...
try {
    nlohmann::json signedTx = subWallet->SignTransaction(tx, payPassword);
} catch (...) {
    // exception process
}

Remove master wallet

Destroy a master wallet created before, and remove local storage

try {
    manager->DestroyWallet(walletID);
} catch (...) {
    // exception process
}

Deinitialize

Delete instance MasterWalletManager before program exit

manager->FlushData();
delete manager;

Demo

https://github.com/elastos/Elastos.ELA.SPV.Cpp/blob/master/Wallet/Wallet.cpp