jl777
7 years ago
committed by
GitHub
11 changed files with 990 additions and 2 deletions
@ -0,0 +1,10 @@ |
|||
cmake_minimum_required(VERSION 2.8.9) |
|||
add_library(etomiclib etomiclib.cpp) |
|||
add_library(etomiccurl etomiccurl.c) |
|||
add_executable(alice alice.c) |
|||
add_executable(bob bob.c) |
|||
include_directories("${CMAKE_SOURCE_DIR}/cpp-ethereum") |
|||
target_link_libraries(etomiccurl PUBLIC curl libcrypto777) |
|||
target_link_libraries(etomiclib PUBLIC ethcore devcrypto devcore etomiccurl) |
|||
target_link_libraries(alice PUBLIC etomiclib) |
|||
target_link_libraries(bob PUBLIC etomiclib etomiccurl) |
@ -0,0 +1,106 @@ |
|||
//
|
|||
// Created by artem on 24.01.18.
|
|||
//
|
|||
#include <stdio.h> |
|||
#include <curl/curl.h> |
|||
#include <stdlib.h> |
|||
#include "etomiclib.h" |
|||
#include <cjson/cJSON.h> |
|||
|
|||
char* aliceContractAddress = "0xe1D4236C5774D35Dc47dcc2E5E0CcFc463A3289c"; |
|||
char* aliceAddress = "0x485d2cc2d13a9e12E4b53D606DB1c8adc884fB8a"; |
|||
char* bobAddress = "0xA7EF3f65714AE266414C9E58bB4bAa4E6FB82B41"; |
|||
char* tokenAddress = "0xc0eb7AeD740E1796992A08962c15661bDEB58003"; |
|||
|
|||
int main(int argc, char** argv) { |
|||
enum { INIT_ETH, INIT_ERC20, ALICE_CLAIMS, BOB_CLAIMS, ALICE_APPROVES_ERC20 }; |
|||
|
|||
if (argc < 2) { |
|||
return 1; |
|||
} |
|||
|
|||
int action = atoi(argv[1]); |
|||
char* result; |
|||
BasicTxData txData; |
|||
switch (action) |
|||
{ |
|||
case INIT_ETH: |
|||
txData.amount = "1000000000000000000"; |
|||
txData.from = aliceAddress; |
|||
txData.to = aliceContractAddress; |
|||
txData.secretKey = getenv("ALICE_PK"); |
|||
|
|||
AliceSendsEthPaymentInput input = { |
|||
.dealId = argv[2], |
|||
.bobAddress = bobAddress, |
|||
.aliceHash = argv[3], |
|||
.bobHash = argv[4] |
|||
}; |
|||
|
|||
result = aliceSendsEthPayment(input, txData); |
|||
break; |
|||
case INIT_ERC20: |
|||
txData.amount = "0"; |
|||
txData.from = aliceAddress; |
|||
txData.to = aliceContractAddress; |
|||
txData.secretKey = getenv("ALICE_PK"); |
|||
|
|||
AliceSendsErc20PaymentInput input1 = { |
|||
.dealId = argv[2], |
|||
.bobAddress = bobAddress, |
|||
.aliceHash = argv[3], |
|||
.bobHash = argv[4], |
|||
.amount = "1000000000000000000", |
|||
.tokenAddress = tokenAddress |
|||
}; |
|||
|
|||
result = aliceSendsErc20Payment(input1, txData); |
|||
break; |
|||
case ALICE_CLAIMS: |
|||
txData.amount = "0"; |
|||
txData.from = aliceAddress; |
|||
txData.to = aliceContractAddress; |
|||
txData.secretKey = getenv("ALICE_PK"); |
|||
|
|||
AliceReclaimsAlicePaymentInput input2 = { |
|||
.dealId = argv[2], |
|||
.bobAddress = bobAddress, |
|||
.aliceHash = argv[3], |
|||
.bobSecret = argv[4], |
|||
.tokenAddress = argv[5], |
|||
.amount = "1000000000000000000" |
|||
}; |
|||
|
|||
result = aliceReclaimsAlicePayment(input2, txData); |
|||
break; |
|||
case BOB_CLAIMS: |
|||
txData.amount = "0"; |
|||
txData.from = bobAddress; |
|||
txData.to = aliceContractAddress; |
|||
txData.secretKey = getenv("BOB_PK"); |
|||
|
|||
BobSpendsAlicePaymentInput input3 = { |
|||
.dealId = argv[2], |
|||
.aliceAddress = aliceAddress, |
|||
.aliceSecret = argv[3], |
|||
.bobHash = argv[4], |
|||
.tokenAddress = argv[5], |
|||
.amount = "1000000000000000000" |
|||
}; |
|||
|
|||
result = bobSpendsAlicePayment(input3, txData); |
|||
break; |
|||
case ALICE_APPROVES_ERC20: |
|||
result = approveErc20( |
|||
"1000000000000000000", |
|||
"0x485d2cc2d13a9e12E4b53D606DB1c8adc884fB8a", |
|||
getenv("ALICE_PK") |
|||
); |
|||
break; |
|||
default: |
|||
return 1; |
|||
} |
|||
printf("%s\n", result); |
|||
free(result); |
|||
return 0; |
|||
} |
@ -0,0 +1,202 @@ |
|||
//
|
|||
// Created by artem on 24.01.18.
|
|||
//
|
|||
#include <stdio.h> |
|||
#include <curl/curl.h> |
|||
#include <stdlib.h> |
|||
#include <inttypes.h> |
|||
#include "etomiclib.h" |
|||
|
|||
char* bobContractAddress = "0x9387Fd3a016bB0205e4e131Dde886B9d2BC000A2"; |
|||
char* aliceAddress = "0x485d2cc2d13a9e12E4b53D606DB1c8adc884fB8a"; |
|||
char* bobAddress = "0xA7EF3f65714AE266414C9E58bB4bAa4E6FB82B41"; |
|||
char* tokenAddress = "0xc0eb7AeD740E1796992A08962c15661bDEB58003"; |
|||
|
|||
int main(int argc, char** argv) |
|||
{ |
|||
enum { |
|||
BOB_ETH_DEPOSIT, |
|||
BOB_ERC20_DEPOSIT, |
|||
BOB_CLAIMS_DEPOSIT, |
|||
ALICE_CLAIMS_DEPOSIT, |
|||
BOB_ETH_PAYMENT, |
|||
BOB_ERC20_PAYMENT, |
|||
BOB_CLAIMS_PAYMENT, |
|||
ALICE_CLAIMS_PAYMENT, |
|||
BOB_APPROVES_ERC20, |
|||
BOB_ETH_BALANCE, |
|||
BOB_ERC20_BALANCE, |
|||
}; |
|||
if (argc < 2) { |
|||
return 1; |
|||
} |
|||
int action = atoi(argv[1]); |
|||
BasicTxData txData; |
|||
char* result; |
|||
switch (action) |
|||
{ |
|||
case BOB_ETH_DEPOSIT: |
|||
txData.amount = "1000000000000000000"; |
|||
txData.from = bobAddress; |
|||
txData.to = bobContractAddress; |
|||
txData.secretKey = getenv("BOB_PK"); |
|||
|
|||
BobSendsEthDepositInput input = { |
|||
.aliceAddress = aliceAddress, |
|||
.depositId = argv[2], |
|||
.bobHash = argv[3] |
|||
}; |
|||
|
|||
result = bobSendsEthDeposit(input, txData); |
|||
printf("%s\n", result); |
|||
free(result); |
|||
break; |
|||
case BOB_ERC20_DEPOSIT: |
|||
txData.amount = "0"; |
|||
txData.from = bobAddress; |
|||
txData.to = bobContractAddress; |
|||
txData.secretKey = getenv("BOB_PK"); |
|||
|
|||
BobSendsErc20DepositInput input1 = { |
|||
.depositId = argv[2], |
|||
.amount = "1000000000000000000", |
|||
.aliceAddress = aliceAddress, |
|||
.bobHash = argv[3], |
|||
.tokenAddress = tokenAddress |
|||
}; |
|||
|
|||
result = bobSendsErc20Deposit(input1, txData); |
|||
printf("%s\n", result); |
|||
free(result); |
|||
break; |
|||
case BOB_CLAIMS_DEPOSIT: |
|||
txData.amount = "0"; |
|||
txData.from = bobAddress; |
|||
txData.to = bobContractAddress; |
|||
txData.secretKey = getenv("BOB_PK"); |
|||
|
|||
BobRefundsDepositInput input2 = { |
|||
.depositId = argv[2], |
|||
.amount = "1000000000000000000", |
|||
.aliceAddress = aliceAddress, |
|||
.tokenAddress = argv[3], |
|||
.aliceCanClaimAfter = argv[4], |
|||
.bobSecret = argv[5] |
|||
}; |
|||
|
|||
result = bobRefundsDeposit(input2, txData); |
|||
printf("%s\n", result); |
|||
free(result); |
|||
break; |
|||
case ALICE_CLAIMS_DEPOSIT: |
|||
txData.amount = "0"; |
|||
txData.from = aliceAddress; |
|||
txData.to = bobContractAddress; |
|||
txData.secretKey = getenv("ALICE_PK"); |
|||
|
|||
AliceClaimsBobDepositInput input3 = { |
|||
.depositId = argv[2], |
|||
.amount = "1000000000000000000", |
|||
.bobAddress = bobAddress, |
|||
.tokenAddress = argv[3], |
|||
.aliceCanClaimAfter = argv[4], |
|||
.bobHash = argv[5] |
|||
}; |
|||
|
|||
result = aliceClaimsBobDeposit(input3, txData); |
|||
printf("%s\n", result); |
|||
free(result); |
|||
break; |
|||
case BOB_ETH_PAYMENT: |
|||
txData.amount = "1000000000000000000"; |
|||
txData.from = bobAddress; |
|||
txData.to = bobContractAddress; |
|||
txData.secretKey = getenv("BOB_PK"); |
|||
|
|||
BobSendsEthPaymentInput input4 = { |
|||
.paymentId = argv[2], |
|||
.aliceHash = argv[3], |
|||
.aliceAddress = aliceAddress |
|||
}; |
|||
|
|||
result = bobSendsEthPayment(input4, txData); |
|||
printf("%s\n", result); |
|||
free(result); |
|||
break; |
|||
case BOB_ERC20_PAYMENT: |
|||
txData.amount = "0"; |
|||
txData.from = bobAddress; |
|||
txData.to = bobContractAddress; |
|||
txData.secretKey = getenv("BOB_PK"); |
|||
|
|||
BobSendsErc20PaymentInput input5 = { |
|||
.paymentId = argv[2], |
|||
.amount = "1000000000000000000", |
|||
.tokenAddress = tokenAddress, |
|||
.aliceAddress = aliceAddress, |
|||
.aliceHash = argv[3] |
|||
}; |
|||
|
|||
result = bobSendsErc20Payment(input5, txData); |
|||
printf("%s\n", result); |
|||
free(result); |
|||
break; |
|||
case BOB_CLAIMS_PAYMENT: |
|||
txData.amount = "0"; |
|||
txData.from = bobAddress; |
|||
txData.to = bobContractAddress; |
|||
txData.secretKey = getenv("BOB_PK"); |
|||
|
|||
BobReclaimsBobPaymentInput input6 = { |
|||
.paymentId = argv[2], |
|||
.aliceAddress = aliceAddress, |
|||
.amount = "1000000000000000000", |
|||
.tokenAddress = argv[3], |
|||
.bobCanClaimAfter = argv[4], |
|||
.aliceHash = argv[5] |
|||
}; |
|||
|
|||
result = bobReclaimsBobPayment(input6, txData); |
|||
printf("%s\n", result); |
|||
free(result); |
|||
break; |
|||
case ALICE_CLAIMS_PAYMENT: |
|||
txData.amount = "0"; |
|||
txData.from = aliceAddress; |
|||
txData.to = bobContractAddress; |
|||
txData.secretKey = getenv("ALICE_PK"); |
|||
|
|||
AliceSpendsBobPaymentInput input7 = { |
|||
.paymentId = argv[2], |
|||
.bobAddress = bobAddress, |
|||
.amount = "1000000000000000000", |
|||
.tokenAddress = argv[3], |
|||
.bobCanClaimAfter = argv[4], |
|||
.aliceSecret = argv[5] |
|||
}; |
|||
|
|||
result = aliceSpendsBobPayment(input7, txData); |
|||
printf("%s\n", result); |
|||
free(result); |
|||
break; |
|||
case BOB_APPROVES_ERC20: |
|||
result = approveErc20( |
|||
"10000000000000000000", |
|||
"0xA7EF3f65714AE266414C9E58bB4bAa4E6FB82B41", |
|||
getenv("BOB_PK") |
|||
|
|||
); |
|||
printf("%s\n", result); |
|||
free(result); |
|||
break; |
|||
case BOB_ETH_BALANCE: |
|||
printf("%" PRIu64 "\n", getEthBalance(bobAddress)); |
|||
break; |
|||
case BOB_ERC20_BALANCE: |
|||
printf("%" PRIu64 "\n", getErc20Balance(bobAddress, tokenAddress)); |
|||
break; |
|||
default: |
|||
return 1; |
|||
} |
|||
return 0; |
|||
} |
@ -0,0 +1,162 @@ |
|||
#include "etomiccurl.h" |
|||
#include <curl/curl.h> |
|||
#include <memory.h> |
|||
#include <stdlib.h> |
|||
#include "../../../includes/cJSON.h" |
|||
|
|||
static char* ethRpcUrl = "https://ropsten.infura.io/y07GHxUyTgeN2mdfOonu"; |
|||
|
|||
struct string { |
|||
char *ptr; |
|||
size_t len; |
|||
}; |
|||
|
|||
void init_eth_string(struct string *s) { |
|||
s->len = 0; |
|||
s->ptr = malloc(s->len+1); |
|||
if (s->ptr == NULL) { |
|||
fprintf(stderr, "malloc() failed\n"); |
|||
exit(EXIT_FAILURE); |
|||
} |
|||
s->ptr[0] = '\0'; |
|||
} |
|||
|
|||
size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s) |
|||
{ |
|||
size_t new_len = s->len + size*nmemb; |
|||
s->ptr = realloc(s->ptr, new_len+1); |
|||
if (s->ptr == NULL) { |
|||
fprintf(stderr, "realloc() failed\n"); |
|||
exit(EXIT_FAILURE); |
|||
} |
|||
memcpy(s->ptr+s->len, ptr, size*nmemb); |
|||
s->ptr[new_len] = '\0'; |
|||
s->len = new_len; |
|||
|
|||
return size*nmemb; |
|||
} |
|||
|
|||
char* sendRequest(char* request) |
|||
{ |
|||
CURL *curl; |
|||
CURLcode res; |
|||
struct curl_slist *headers = NULL; |
|||
curl = curl_easy_init(); |
|||
if (curl) { |
|||
struct string s; |
|||
init_eth_string(&s); |
|||
|
|||
headers = curl_slist_append(headers, "Accept: application/json"); |
|||
headers = curl_slist_append(headers, "Content-Type: application/json"); |
|||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); |
|||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); |
|||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); |
|||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); |
|||
curl_easy_setopt(curl, CURLOPT_URL, ethRpcUrl); |
|||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request); |
|||
/* Perform the request, res will get the return code */ |
|||
res = curl_easy_perform(curl); |
|||
/* Check for errors */ |
|||
if (res != CURLE_OK) { |
|||
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); |
|||
} |
|||
|
|||
/* always cleanup */ |
|||
curl_easy_cleanup(curl); |
|||
return s.ptr; |
|||
} else { |
|||
return NULL; |
|||
} |
|||
} |
|||
|
|||
char* sendRawTx(char* rawTx) |
|||
{ |
|||
char* string; |
|||
cJSON *request = cJSON_CreateObject(); |
|||
cJSON *params = cJSON_CreateArray(); |
|||
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0")); |
|||
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_sendRawTransaction")); |
|||
cJSON_AddItemToArray(params, cJSON_CreateString(rawTx)); |
|||
cJSON_AddItemToObject(request, "params", params); |
|||
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2)); |
|||
string = cJSON_PrintUnformatted(request); |
|||
char* requestResult = sendRequest(string); |
|||
cJSON *json = cJSON_Parse(requestResult); |
|||
cJSON_Delete(request); |
|||
char* tmp = cJSON_GetObjectItem(json, "result")->valuestring; |
|||
char* txId = (char*)malloc(strlen(tmp) + 1); |
|||
strcpy(txId, tmp); |
|||
cJSON_Delete(json); |
|||
free(requestResult); |
|||
return txId; |
|||
} |
|||
|
|||
int getNonce(char* address) |
|||
{ |
|||
char* string; |
|||
cJSON *request = cJSON_CreateObject(); |
|||
cJSON *params = cJSON_CreateArray(); |
|||
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0")); |
|||
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_getTransactionCount")); |
|||
cJSON_AddItemToArray(params, cJSON_CreateString(address)); |
|||
cJSON_AddItemToArray(params, cJSON_CreateString("pending")); |
|||
cJSON_AddItemToObject(request, "params", params); |
|||
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2)); |
|||
string = cJSON_PrintUnformatted(request); |
|||
char* requestResult = sendRequest(string); |
|||
cJSON_Delete(request); |
|||
cJSON *json = cJSON_Parse(requestResult); |
|||
int nonce = (int)strtol(cJSON_GetObjectItem(json, "result")->valuestring, NULL, 0); |
|||
cJSON_Delete(json); |
|||
free(requestResult); |
|||
return nonce; |
|||
} |
|||
|
|||
char* getEthBalanceRequest(char* address) |
|||
{ |
|||
char* string; |
|||
cJSON *request = cJSON_CreateObject(); |
|||
cJSON *params = cJSON_CreateArray(); |
|||
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0")); |
|||
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_getBalance")); |
|||
cJSON_AddItemToArray(params, cJSON_CreateString(address)); |
|||
cJSON_AddItemToArray(params, cJSON_CreateString("latest")); |
|||
cJSON_AddItemToObject(request, "params", params); |
|||
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2)); |
|||
string = cJSON_PrintUnformatted(request); |
|||
char* requestResult = sendRequest(string); |
|||
cJSON_Delete(request); |
|||
cJSON *json = cJSON_Parse(requestResult); |
|||
char* tmp = cJSON_GetObjectItem(json, "result")->valuestring; |
|||
char* balance = (char*)malloc(strlen(tmp) + 1); |
|||
strcpy(balance, tmp); |
|||
cJSON_Delete(json); |
|||
free(requestResult); |
|||
return balance; |
|||
} |
|||
|
|||
char* ethCall(char* to, const char* data) |
|||
{ |
|||
char* string; |
|||
cJSON *request = cJSON_CreateObject(); |
|||
cJSON *params = cJSON_CreateArray(); |
|||
cJSON *txObject = cJSON_CreateObject(); |
|||
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0")); |
|||
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_call")); |
|||
cJSON_AddStringToObject(txObject, "to", to); |
|||
cJSON_AddStringToObject(txObject, "data", data); |
|||
cJSON_AddItemToArray(params, txObject); |
|||
cJSON_AddItemToArray(params, cJSON_CreateString("latest")); |
|||
cJSON_AddItemToObject(request, "params", params); |
|||
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2)); |
|||
string = cJSON_PrintUnformatted(request); |
|||
char* requestResult = sendRequest(string); |
|||
cJSON_Delete(request); |
|||
cJSON *json = cJSON_Parse(requestResult); |
|||
char* tmp = cJSON_GetObjectItem(json, "result")->valuestring; |
|||
char* balance = (char*)malloc(strlen(tmp) + 1); |
|||
strcpy(balance, tmp); |
|||
cJSON_Delete(json); |
|||
free(requestResult); |
|||
return balance; |
|||
} |
@ -0,0 +1,12 @@ |
|||
#ifdef __cplusplus |
|||
extern "C"{ |
|||
#endif |
|||
|
|||
char* sendRawTx(char* rawTx); |
|||
char* ethCall(char* to, const char* data); |
|||
int getNonce(char* address); |
|||
char* getEthBalanceRequest(char* address); |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
@ -0,0 +1,357 @@ |
|||
//
|
|||
// Created by artem on 24.01.18.
|
|||
//
|
|||
#include "etomiclib.h" |
|||
#include "etomiccurl.h" |
|||
#include <iostream> |
|||
#include <cpp-ethereum/libethcore/Common.h> |
|||
#include <cpp-ethereum/libethcore/CommonJS.h> |
|||
#include <cpp-ethereum/libethcore/TransactionBase.h> |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
char* stringStreamToChar(std::stringstream& ss) |
|||
{ |
|||
const std::string tmp = ss.str(); |
|||
auto result = (char*)malloc(strlen(tmp.c_str()) + 1); |
|||
strcpy(result, tmp.c_str()); |
|||
return result; |
|||
} |
|||
|
|||
TransactionSkeleton txDataToSkeleton(BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx; |
|||
tx.from = jsToAddress(txData.from); |
|||
tx.to = jsToAddress(txData.to); |
|||
tx.value = jsToU256(txData.amount); |
|||
tx.gas = 300000; |
|||
tx.gasPrice = 100 * exp10<9>(); |
|||
tx.nonce = getNonce(txData.from); |
|||
return tx; |
|||
} |
|||
|
|||
char* signTx(TransactionSkeleton& tx, char* secret) |
|||
{ |
|||
Secret& secretKey = *(new Secret(secret)); |
|||
auto baseTx = new TransactionBase(tx, secretKey); |
|||
RLPStream& rlpStream = *(new RLPStream()); |
|||
baseTx->streamRLP(rlpStream); |
|||
std::stringstream& ss = *(new std::stringstream); |
|||
ss << rlpStream.out(); |
|||
return stringStreamToChar(ss); |
|||
} |
|||
|
|||
char* approveErc20(char* amount, char* from, char* secret) |
|||
{ |
|||
TransactionSkeleton tx; |
|||
tx.from = jsToAddress(from); |
|||
tx.to = jsToAddress("0xc0eb7AeD740E1796992A08962c15661bDEB58003"); |
|||
tx.value = 0; // exp10<18>();
|
|||
tx.gas = 300000; |
|||
tx.gasPrice = 100 * exp10<9>(); |
|||
tx.nonce = getNonce(from); |
|||
std::stringstream ss; |
|||
ss << "0x095ea7b3" |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress("0xe1D4236C5774D35Dc47dcc2E5E0CcFc463A3289c")) |
|||
<< toHex(toBigEndian(jsToU256(amount))); |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, secret); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0x47c7b6e2" |
|||
<< toHex(jsToBytes(input.dealId)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.bobAddress)) |
|||
<< toHex(jsToBytes(input.aliceHash)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToBytes(input.bobHash)) |
|||
<< "000000000000000000000000"; |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0x184db3bf" |
|||
<< toHex(jsToBytes(input.dealId)) |
|||
<< toHex(toBigEndian(jsToU256(input.amount))) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.bobAddress)) |
|||
<< toHex(jsToBytes(input.aliceHash)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToBytes(input.bobHash)) |
|||
<< "000000000000000000000000" |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.tokenAddress)); |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0x8b9a167a" |
|||
<< toHex(jsToBytes(input.dealId)) |
|||
<< toHex(toBigEndian(jsToU256(input.amount))) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.tokenAddress)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.bobAddress)) |
|||
<< toHex(jsToBytes(input.aliceHash)) |
|||
<< "000000000000000000000000" |
|||
<< "00000000000000000000000000000000000000000000000000000000000000c0" |
|||
<< "0000000000000000000000000000000000000000000000000000000000000020" |
|||
<< toHex(jsToBytes(input.bobSecret)); |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0x392ec66b" |
|||
<< toHex(jsToBytes(input.dealId)) |
|||
<< toHex(toBigEndian(jsToU256(input.amount))) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.tokenAddress)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.aliceAddress)) |
|||
<< toHex(jsToBytes(input.bobHash)) |
|||
<< "000000000000000000000000" |
|||
<< "00000000000000000000000000000000000000000000000000000000000000c0" |
|||
<< "0000000000000000000000000000000000000000000000000000000000000020" |
|||
<< toHex(jsToBytes(input.aliceSecret)); |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0xc2c5143f" |
|||
<< toHex(jsToBytes(input.depositId)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.aliceAddress)) |
|||
<< toHex(jsToBytes(input.bobHash)) |
|||
<< "000000000000000000000000"; |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0xce8bbe4b" |
|||
<< toHex(jsToBytes(input.depositId)) |
|||
<< toHex(toBigEndian(jsToU256(input.amount))) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.aliceAddress)) |
|||
<< toHex(jsToBytes(input.bobHash)) |
|||
<< "000000000000000000000000" |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.tokenAddress)); |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0x1dbe6508" |
|||
<< toHex(jsToBytes(input.depositId)) |
|||
<< toHex(toBigEndian(jsToU256(input.amount))) |
|||
<< toHex(toBigEndian(jsToU256(input.aliceCanClaimAfter))) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.aliceAddress)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.tokenAddress)) |
|||
<< "00000000000000000000000000000000000000000000000000000000000000c0" |
|||
<< "0000000000000000000000000000000000000000000000000000000000000020" |
|||
<< toHex(jsToBytes(input.bobSecret)); |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0x960173b5" |
|||
<< toHex(jsToBytes(input.depositId)) |
|||
<< toHex(toBigEndian(jsToU256(input.amount))) |
|||
<< toHex(toBigEndian(jsToU256(input.aliceCanClaimAfter))) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.bobAddress)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.tokenAddress)) |
|||
<< toHex(jsToBytes(input.bobHash)) |
|||
<< "000000000000000000000000"; |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0xcf36fe8e" |
|||
<< toHex(jsToBytes(input.paymentId)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.aliceAddress)) |
|||
<< toHex(jsToBytes(input.aliceHash)) |
|||
<< "000000000000000000000000"; |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0x34f64dfd" |
|||
<< toHex(jsToBytes(input.paymentId)) |
|||
<< toHex(toBigEndian(jsToU256(input.amount))) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.aliceAddress)) |
|||
<< toHex(jsToBytes(input.aliceHash)) |
|||
<< "000000000000000000000000" |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.tokenAddress)); |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0xb7cc2312" |
|||
<< toHex(jsToBytes(input.paymentId)) |
|||
<< toHex(toBigEndian(jsToU256(input.amount))) |
|||
<< toHex(toBigEndian(jsToU256(input.bobCanClaimAfter))) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.aliceAddress)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.tokenAddress)) |
|||
<< toHex(jsToBytes(input.aliceHash)) |
|||
<< "000000000000000000000000"; |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData) |
|||
{ |
|||
TransactionSkeleton tx = txDataToSkeleton(txData); |
|||
std::stringstream ss; |
|||
ss << "0x97004255" |
|||
<< toHex(jsToBytes(input.paymentId)) |
|||
<< toHex(toBigEndian(jsToU256(input.amount))) |
|||
<< toHex(toBigEndian(jsToU256(input.bobCanClaimAfter))) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.bobAddress)) |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(input.tokenAddress)) |
|||
<< "00000000000000000000000000000000000000000000000000000000000000c0" |
|||
<< "0000000000000000000000000000000000000000000000000000000000000020" |
|||
<< toHex(jsToBytes(input.aliceSecret)); |
|||
tx.data = jsToBytes(ss.str()); |
|||
char* rawTx = signTx(tx, txData.secretKey); |
|||
char* result = sendRawTx(rawTx); |
|||
free(rawTx); |
|||
return result; |
|||
} |
|||
|
|||
char* privKey2Addr(char* privKey) |
|||
{ |
|||
Secret& secretKey = *(new Secret(privKey)); |
|||
std::stringstream& ss = *(new std::stringstream); |
|||
ss << "0x" << toAddress(secretKey); |
|||
return stringStreamToChar(ss); |
|||
}; |
|||
|
|||
char* pubKey2Addr(char* pubKey) |
|||
{ |
|||
Public& publicKey = *(new Public(pubKey)); |
|||
std::stringstream& ss = *(new std::stringstream); |
|||
ss << "0x" << toAddress(publicKey); |
|||
return stringStreamToChar(ss); |
|||
}; |
|||
|
|||
char* getPubKeyFromPriv(char* privKey) |
|||
{ |
|||
Public publicKey = toPublic(*(new Secret(privKey))); |
|||
std::stringstream& ss = *(new std::stringstream); |
|||
ss << "0x" << publicKey; |
|||
return stringStreamToChar(ss); |
|||
} |
|||
|
|||
uint64_t getEthBalance(char* address) |
|||
{ |
|||
char* hexBalance = getEthBalanceRequest(address); |
|||
// convert wei to satoshi
|
|||
u256 balance = jsToU256(hexBalance) / exp10<10>(); |
|||
free(hexBalance); |
|||
return static_cast<uint64_t>(balance); |
|||
} |
|||
|
|||
uint64_t getErc20Balance(char* address, char* tokenAddress) |
|||
{ |
|||
std::stringstream ss; |
|||
ss << "0x70a08231" |
|||
<< "000000000000000000000000" |
|||
<< toHex(jsToAddress(address)); |
|||
std::stringstream& resultStream = *(new std::stringstream); |
|||
char* hexBalance = ethCall(tokenAddress, ss.str().c_str()); |
|||
// convert wei to satoshi
|
|||
u256 balance = jsToU256(hexBalance) / exp10<10>(); |
|||
free(hexBalance); |
|||
return static_cast<uint64_t>(balance); |
|||
} |
@ -0,0 +1,135 @@ |
|||
//
|
|||
// Created by artem on 24.01.18.
|
|||
//
|
|||
#include <stdint.h> |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
typedef struct { |
|||
char* from; |
|||
char* to; |
|||
char* amount; |
|||
char* secretKey; |
|||
} BasicTxData; |
|||
|
|||
typedef struct { |
|||
char* dealId; |
|||
char* bobAddress; |
|||
char* aliceHash; |
|||
char* bobHash; |
|||
} AliceSendsEthPaymentInput; |
|||
|
|||
typedef struct { |
|||
char* dealId; |
|||
char* amount; |
|||
char* tokenAddress; |
|||
char* bobAddress; |
|||
char* aliceHash; |
|||
char* bobHash; |
|||
} AliceSendsErc20PaymentInput; |
|||
|
|||
typedef struct { |
|||
char* dealId; |
|||
char* amount; |
|||
char* tokenAddress; |
|||
char* bobAddress; |
|||
char* aliceHash; |
|||
char* bobSecret; |
|||
} AliceReclaimsAlicePaymentInput; |
|||
|
|||
typedef struct { |
|||
char* dealId; |
|||
char* amount; |
|||
char* tokenAddress; |
|||
char* aliceAddress; |
|||
char* aliceSecret; |
|||
char* bobHash; |
|||
} BobSpendsAlicePaymentInput; |
|||
|
|||
typedef struct { |
|||
char* depositId; |
|||
char* aliceAddress; |
|||
char* bobHash; |
|||
} BobSendsEthDepositInput; |
|||
|
|||
typedef struct { |
|||
char* depositId; |
|||
char* amount; |
|||
char* tokenAddress; |
|||
char* aliceAddress; |
|||
char* bobHash; |
|||
} BobSendsErc20DepositInput; |
|||
|
|||
typedef struct { |
|||
char* depositId; |
|||
char* amount; |
|||
char* tokenAddress; |
|||
char* aliceAddress; |
|||
char* bobSecret; |
|||
char* aliceCanClaimAfter; |
|||
} BobRefundsDepositInput; |
|||
|
|||
typedef struct { |
|||
char* depositId; |
|||
char* amount; |
|||
char* tokenAddress; |
|||
char* bobAddress; |
|||
char* bobHash; |
|||
char* aliceCanClaimAfter; |
|||
} AliceClaimsBobDepositInput; |
|||
|
|||
typedef struct { |
|||
char* paymentId; |
|||
char* aliceAddress; |
|||
char* aliceHash; |
|||
} BobSendsEthPaymentInput; |
|||
|
|||
typedef struct { |
|||
char* paymentId; |
|||
char* amount; |
|||
char* tokenAddress; |
|||
char* aliceAddress; |
|||
char* aliceHash; |
|||
} BobSendsErc20PaymentInput; |
|||
|
|||
typedef struct { |
|||
char* paymentId; |
|||
char* amount; |
|||
char* tokenAddress; |
|||
char* aliceAddress; |
|||
char* aliceHash; |
|||
char* bobCanClaimAfter; |
|||
} BobReclaimsBobPaymentInput; |
|||
|
|||
typedef struct { |
|||
char* paymentId; |
|||
char* amount; |
|||
char* tokenAddress; |
|||
char* aliceSecret; |
|||
char* bobAddress; |
|||
char* bobCanClaimAfter; |
|||
} AliceSpendsBobPaymentInput; |
|||
|
|||
char* approveErc20(char* amount, char* from, char* secret); |
|||
char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData); |
|||
char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData); |
|||
char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData); |
|||
char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData); |
|||
char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData); |
|||
char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData); |
|||
char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData); |
|||
char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData); |
|||
char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData); |
|||
char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData); |
|||
char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData); |
|||
char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData); |
|||
char* privKey2Addr(char* privKey); |
|||
char* pubKey2Addr(char* pubKey); |
|||
char* getPubKeyFromPriv(char* privKey); |
|||
uint64_t getEthBalance(char* address); |
|||
uint64_t getErc20Balance(char* address, char* tokenAddress); |
|||
// Your prototype or Definition
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
Loading…
Reference in new issue