Published 3 July 2019

Examples: C++: Deploy Smart contract

Project:

https://github.com/CREDITSCOM/examples

Branch:

https://github.com/CREDITSCOM/examples/tree/master/API/CreditsCPlusPlusDemoCMake

 

In order to deploy a Smart Contract, wallet’s public and private keys, and public address of transfer destination have to be shared to the class Client

// gets integer and fraction parts of the tokens amount for transfer and reward amount (the transfer this amount equals 0.9 by default)

void client::deploy_smart(std::string code, double fee_value)

{

  try

  {

    auto tr = make_transaction_with_smart_contract(code, fee_value);

    TransactionFlowResult tfr;

    m_api->TransactionFlow(tfr, *tr);

    tfr.printTo(std::cout);

  }

  catch (const std::exception ex)

  {

    throw std::exception(ex.what());

  }

}

 

// method to create a transaction, form its signature and to sign the transaction

std::unique_ptr<api::Transaction> client::make_transaction_with_smart_contract(std::string code, double fee_value)

{

  if (code.length() == 0)

  {

    code = "import com.credits.scapi.annotations.*; import com.credits.scapi.v0.*; public class MySmartContract extends SmartContract { public MySmartContract() {} public String hello2(String say) { return \"Hello\" + say; } }";

    auto tr = std::make_unique<api::Transaction>();

    // set true for transferring optional parameters

    tr->__isset.smartContract = true;

    tr->smartContract.__isset.smartContractDeploy = true;

  }

  WalletTransactionsCountGetResult wtcgr;

  auto& pka = m_keys->PublicKeyAddress(); 

  m_api->WalletTransactionsCountGet(wtcgr, pka);

  tr->id = wtcgr.lastTransactionInnerId + 1;

  tr->source = std::string{ m_keys->PublicKeyAddress() };

  tr->amount.integral = 0;

  tr->amount.fraction = 0;

  tr->fee.commission = fee(fee_value);

  tr->currency = 1;

  std::vector<byte> target;

  copy(&((unsigned char*)tr->source.c_str())[0],  ((unsigned char*)tr->source.c_str())[tr->source.size()],

  back_inserter(target));

  cp(target, tr->id, 6, false);

  SmartContractCompileResult sccr;

  m_api->SmartContractCompile(sccr, code);

  if (sccr.status.code == 0)

  {

    for (int i = 0; i < sccr.byteCodeObjects.size(); i++)

    {

      copy(&((unsigned char*)sccr.byteCodeObjects[i].byteCode.c_str())[0], &((unsigned char*)sccr.byteCodeObjects[i].byteCode.c_str())[sccr.byteCodeObjects[i].byteCode.size()],

      back_inserter(target));

    }

  }

  else

  {

    throw std::exception(sccr.status.message.c_str());

  }

  tr->smartContract.smartContractDeploy.sourceCode = code;

  tr->smartContract.forgetNewState = false;

  byte hash[32];

  blake2s(hash, BLAKE2S_OUTBYTES, target.data(), target.size(), nullptr, 0);

  std::copy(&hash[0], &hash[32], back_inserter(tr->target));

  std::vector<byte> msg;

  cp(msg, tr->id, 6, false);

  copy(&((unsigned char*)tr->source.c_str())[0], &((unsigned char*)tr->source.c_str())[tr->source.size()], back_inserter(msg));

  copy(&((unsigned char*)tr->target.c_str())[0], &((unsigned char*)tr->target.c_str())[tr->target.size()], back_inserter(msg));

  cp(msg, tr->amount.integral, 4, false);

  cp(msg, tr->amount.fraction, 8, false);

  cp(msg, tr->fee.commission, 2, false);

  msg.push_back(1);

  msg.push_back(1);

  std::vector<byte> uf{ 11, 0, 1, 0, 0, 0, 0, 15, 0, 2, 12, 0, 0, 0, 0, 15, 0, 3, 11, 0, 0, 0, 0, 2, 0, 4, 0, 12, 0, 5, 11, 0, 1 };

  int32_t x = (int32_t)code.size();

  cp(uf, x, 4, true);

  copy(&((unsigned char*)code.c_str())[0], &((unsigned char*)code.c_str())[code.size()], back_inserter(uf));

  uf.insert(uf.end(), { 15, 0, 2, 12 });

  x = (int32_t)sccr.byteCodeObjects.size();

  cp(uf, x, 4, true);

  for (size_t i = 0; i < sccr.byteCodeObjects.size(); i++)

  {

    uf.insert(uf.end(), { 11, 0, 1 });

    x = (int32_t)sccr.byteCodeObjects[i].name.size();

    cp(uf, x, 4, true);

    copy(&((unsigned char*)sccr.byteCodeObjects[i].name.c_str())[0], &((unsigned char*)sccr.byteCodeObjects[i].name.c_str())[sccr.byteCodeObjects[i].name.size()],

    back_inserter(uf));

    uf.insert(uf.end(), { 11, 0, 2 });

    x = (int32_t)sccr.byteCodeObjects[i].byteCode.size();

    cp(uf, x, 4, true);

    copy(&sccr.byteCodeObjects[i].byteCode[0], &sccr.byteCodeObjects[i].byteCode[sccr.byteCodeObjects[i].byteCode.size()], back_inserter(uf));

    ByteCodeObject nbco;

    nbco.name = sccr.byteCodeObjects[i].name;

    nbco.byteCode = sccr.byteCodeObjects[i].byteCode;

    tr->smartContract.smartContractDeploy.byteCodeObjects.push_back(nbco);

    uf.push_back(0);

  }

  uf.insert(uf.end(), { 11, 0, 3, 0, 0, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0 });

  uf.push_back(0);

  x = (int32_t)uf.size();

  cp(msg, x, 4, false);

  copy(uf.begin(), uf.end(), back_inserter(msg));

  unsigned char signature[SIGNATURE_LEN];

  unsigned long long signatureLen;

  crypto_sign_detached(signature, &signatureLen, msg.data(), msg.size(), (unsigned char*)m_keys->PrivateKeyAddress().c_str());

  if (crypto_sign_verify_detached(signature, msg.data(), msg.size(), (unsigned char*)tr->source.c_str()) != 0)

  {

    throw std::exception("Incorrect signature!");

  }

  tr->signature = std::string(reinterpret_cast<char*>(signature), SIGNATURE_LEN);

  return std::move(tr);

}

Call example

int main(int argc, char* argv[])

{

  if (argc != 6)

  {

    cout << "Usage: main.exe NodeIpAddress NodePort YourPublicKey YourPrivateKey TargetPublicKey" << std::endl;

    return 1;

  }

  auto c = make_unique<client>(argv[1], atoi(argv[2]));

  c->set_keys(argv[3], argv[4], argv[5]);

  cout << " ****** Credits API Demo C++ ******" << endl;

  cout << endl << "****** Deploy Smart Contract ******" << endl;

  // empty string means default smart contract, i.e. test smart contract, will be deployed

  c->deploy_smart("", 1);

  cout << endl << " ****** End ******" << endl << endl;

}

Votes 0, average rating 0

Contents