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