Skip to content

Commit

Permalink
IOS-443: Ethereum work-in-progress litecoin-foundation#7
Browse files Browse the repository at this point in the history
  • Loading branch information
Ed Gamble committed Feb 28, 2018
1 parent 640bd32 commit 95e3fcf
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 60 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@
*.xcworkspace
*.xcodeproj

.idea/
.idea/

test
22 changes: 18 additions & 4 deletions ethereum/BREthereumAccount.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <malloc.h>
#include <stdlib.h>
#include <BRBIP39Mnemonic.h>
#include <string.h>
#include <BRKey.h>
Expand Down Expand Up @@ -89,12 +89,12 @@ accountCreatePrimaryAddress (BREthereumAccount account);

//
// Locale-Based BIP-39 Word List
static char **sharedWordList = NULL;
static const char **sharedWordList;

#define WORD_LIST_LENGTH 2048

extern int
installSharedWordList (char *wordList[], int wordListLength) {
installSharedWordList (const char *wordList[], int wordListLength) {
if (BIP39_WORDLIST_COUNT != wordListLength)
return 0;

Expand Down Expand Up @@ -171,6 +171,10 @@ addressGetPublicKeyHash160 (BREthereumAddress address) {
return BRKeyHash160(&address->key);
}

// https://kobl.one/blog/create-full-ethereum-keypair-and-address/#derive-the-ethereum-address-from-the-public-key
// The private key must be 32 bytes and not begin with 0x00 and the public one must be
// uncompressed and 64 bytes long or 65 with the constant 0x04 prefix.
// More on that in the next section.
extern char *
addressGetPublicKeyKeccak256 (BREthereumAddress address) {
// https://ethereum.stackexchange.com/a/3619/33128
Expand All @@ -181,9 +185,18 @@ addressGetPublicKeyKeccak256 (BREthereumAddress address) {

// Take the last 20 bytes, convert to hex, prefix with '0x' -> 42
char *string = malloc (43);
char *s = string;

*s++ = '0';
*s++ = 'x';

for (int index = 12; index < 32; index++) {
*s++ = _hexc (md[index]);
*s++ = _hexc (md[index] >> 4);
}
*s = '\0';

return s;
}

//
Expand Down Expand Up @@ -264,7 +277,8 @@ accountSignBytes(BREthereumAccount account,
BREthereumAddress address,
BREthereumSignatureType type,
uint8_t *bytes,
size_t bytesCount) {
size_t bytesCount,
const char *paperKey) {
BREthereumSignature signature;

signature.type = type;
Expand Down
7 changes: 5 additions & 2 deletions ethereum/BREthereumAccount.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
extern "C" {
#endif

#include <BRInt.h>

//
// BIP39 Word List
//
Expand All @@ -42,7 +44,7 @@ extern "C" {
* @return
*/
extern int
installSharedWordList (char *wordList[], int wordListLength);
installSharedWordList (const char *wordList[], int wordListLength);

//
// Address
Expand Down Expand Up @@ -171,7 +173,8 @@ accountSignBytes(BREthereumAccount account,
BREthereumAddress address,
BREthereumSignatureType type,
uint8_t *bytes,
size_t bytesCount);
size_t bytesCount,
const char *paperKey);

#ifdef __cplusplus
}
Expand Down
12 changes: 6 additions & 6 deletions ethereum/BREthereumEther.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <malloc.h>
#include <stdlib.h>
#include "BREthereumEther.h"

static UInt256
Expand Down Expand Up @@ -87,7 +87,7 @@ etherGetValueString(const BREthereumEther ether,
extern BREthereumEther
etherCreate(const UInt256 value, BREthereumEtherUnit unit) {
BREthereumEther ether;
ether.positive = TRUE;
ether.positive = ETHEREUM_BOOLEAN_TRUE;

switch (unit) {
case WEI: ether.valueInWEI = value;
Expand Down Expand Up @@ -116,7 +116,7 @@ extern BREthereumEther
etherNegate (BREthereumEther e) {
BREthereumEther ether;

ether.positive = e.positive == TRUE ? FALSE : TRUE;
ether.positive = e.positive == ETHEREUM_BOOLEAN_TRUE ? ETHEREUM_BOOLEAN_FALSE : ETHEREUM_BOOLEAN_TRUE;
ether.valueInWEI = e.valueInWEI;

return ether;
Expand Down Expand Up @@ -154,14 +154,14 @@ etherSub (BREthereumEther e1, BREthereumEther e2) {
//
extern BREthereumBoolean
etherIsEQ (BREthereumEther e1, BREthereumEther e2) {
return UInt256Eq (e1.valueInWEI, e2.valueInWEI) ? TRUE : FALSE;
return UInt256Eq (e1.valueInWEI, e2.valueInWEI) ? ETHEREUM_BOOLEAN_TRUE : ETHEREUM_BOOLEAN_FALSE;
}

//

extern BREthereumBoolean
etherIsGT (BREthereumEther e1, BREthereumEther e2) {
return FALSE;
return ETHEREUM_BOOLEAN_FALSE;
}

extern BREthereumBoolean
Expand All @@ -171,7 +171,7 @@ etherIsGE (BREthereumEther e1, BREthereumEther e2) {

extern BREthereumBoolean
etherIsZero (BREthereumEther e) {
return UInt256IsZero (e.valueInWEI) ? TRUE : FALSE;
return UInt256IsZero (e.valueInWEI) ? ETHEREUM_BOOLEAN_TRUE : ETHEREUM_BOOLEAN_FALSE;
}


Expand Down
8 changes: 4 additions & 4 deletions ethereum/BREthereumEther.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ extern "C" {
#endif

typedef enum {
TRUE = 0, // INTENTIONALLY 'backwards'
FALSE = 1
ETHEREUM_BOOLEAN_TRUE = 0, // INTENTIONALLY 'backwards'
ETHEREUM_BOOLEAN_FALSE = 1
} BREthereumBoolean;

#define ETHEREUM_BOOLEAN_IS_TRUE(x) ((x) == TRUE)
#define ETHEREUM_BOOLEAN_IS_FALSE(x) ((x) == FALSE)
#define ETHEREUM_BOOLEAN_IS_TRUE(x) ((x) == ETHEREUM_BOOLEAN_TRUE)
#define ETHEREUM_BOOLEAN_IS_FALSE(x) ((x) == ETHEREUM_BOOLEAN_FALSE)

typedef enum {
WEI = 0,
Expand Down
11 changes: 9 additions & 2 deletions ethereum/BREthereumHolding.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,16 @@
#include "BREthereum.h"

extern BREthereumToken
tokenCreate (/* ... */) {
tokenCreate (char *address,
BREthereumGas gasLimit,
BREthereumGasPrice gasPrice) {
BREthereumToken token = tokenCreateNone();
// fill in

// TODO: Copy address or what (BREthereumToken is a value type....)
token.address = address;
token.gasLimit = gasLimit;
token.gasPrice = gasPrice;

return token;
}

Expand Down
19 changes: 16 additions & 3 deletions ethereum/BREthereumHolding.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,27 @@ holdingGetType (BREthereumHolding holding);
* A Ethereum Token defines an ERC20 Token
*/
typedef struct BREthereumTokenRecord {
int pending1; // token identifier
int pending2; //
/**
* An Ethereum '0x' address for the token's contract.
*/
char *address;

/**
*
*/
BREthereumGas gasLimit;

/**
*
*/
BREthereumGasPrice gasPrice;

} BREthereumToken;

extern BREthereumToken
tokenCreate (/* ... */);
tokenCreate (char *address,
BREthereumGas gasLimit,
BREthereumGasPrice gasPrice);

extern BREthereumToken
tokenCreateNone ();
Expand Down
4 changes: 2 additions & 2 deletions ethereum/BREthereumTransaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include "BREthereumTransaction.h"

Expand Down Expand Up @@ -116,7 +116,7 @@ transactionSetSigner (BREthereumTransaction transaction, BREthereumAccount accou

extern BREthereumBoolean
transactionIsSigned (BREthereumTransaction transaction) {
return NULL != transactionGetSigner (transaction) ? TRUE : FALSE;
return NULL != transactionGetSigner (transaction) ? ETHEREUM_BOOLEAN_TRUE : ETHEREUM_BOOLEAN_FALSE;
}

//
Expand Down
82 changes: 47 additions & 35 deletions ethereum/BREthereumWallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <malloc.h>
#include <stdlib.h>
#include <assert.h>
#include "BREthereum.h"
#include "BREthereumAccount.h"
Expand Down Expand Up @@ -97,19 +97,25 @@ walletCreateDetailed (BREthereumAccount account,
BREthereumAddress address,
BREthereumWalletHoldingType type,
BREthereumToken optionalToken) {
BREthereumWallet wallet = calloc (1, sizeof (struct BREthereumWalletRecord));

assert (NULL != account);
wallet->account = account;

assert (NULL != address);

BREthereumWallet wallet = calloc(1, sizeof(struct BREthereumWalletRecord));

wallet->account = account;
wallet->address = address;

wallet->holding = holdingCreate(type);
wallet->token = optionalToken;
wallet->token = optionalToken;

wallet->defaultGasLimit = NULL == optionalToken
? walletCreateDefaultGasLimit(wallet)
: tokenGetGasLimit (optionalToken);

wallet->defaultGasLimit = walletCreateDefaultGasLimit (wallet);
wallet->defaultGasPrice = walletCreateDefaultGasPrice (wallet);
wallet->defaultGasPrice = NULL == optionalToken
? walletCreateDefaultGasPrice(wallet)
: tokenGetGasPrice (optionalToken);

// nonce = eth.getTransactionCount(<account>)
return wallet;
Expand All @@ -120,7 +126,7 @@ walletCreate(BREthereumAccount account)
{
return walletCreateWithAddress
(account,
accountCreateAddress(account));
accountGetPrimaryAddress(account));
}

extern BREthereumWallet
Expand Down Expand Up @@ -174,33 +180,19 @@ walletCreateTransactionDetailed(BREthereumWallet wallet,
nonce);
}


/**
* Sign the transaction.
*
* @param wallet
* @param transaction
* @param paperKey
*/
extern void
walletSignTransaction(BREthereumWallet wallet,
BREthereumTransaction transaction) {
transactionSetSigner(transaction, wallet->account);

// Maybe sign and cache; maybe defer until needed (lazy sign).
}

static char *
walletDataForHolding (BREthereumWallet wallet) {
// TODO: Implement
switch (wallet->holding.type) {
case WALLET_HOLDING_ETHER:
return "ether";

case WALLET_HOLDING_TOKEN:
return "token";
}
}

extern BRRlpData // TODO: is this the actual result?
walletGetRawTransaction(BREthereumWallet wallet,
BREthereumTransaction transaction) {

// TODO: This is properly done in 'transaction` (if `transaction` sees `account`-ish)
BREthereumTransaction transaction,
const char *paperKey) {

// TODO: Perhaps this is unneeded, if already provided.
// Fill in the transaction data appropriate for the holding (ETHER or TOKEN)
transactionSetData(transaction, walletDataForHolding(wallet));

Expand All @@ -214,16 +206,36 @@ walletGetRawTransaction(BREthereumWallet wallet,
wallet->address,
SIGNATURE_TYPE_VRS,
transactionUnsignedRLP.bytes,
transactionUnsignedRLP.bytesCount);
transactionUnsignedRLP.bytesCount,
paperKey);

// Attach the signature
transactionSetVRS(transaction,
signature.sig.bar.v,
signature.sig.bar.r,
signature.sig.bar.s);

// RLP Encode the SIGNED transaction.
return transactionEncodeRLP(transaction, TRANSACTION_RLP_SIGNED);
transactionSetSigner(transaction, wallet->account);
}

static char *
walletDataForHolding (BREthereumWallet wallet) {
// TODO: Implement
switch (wallet->holding.type) {
case WALLET_HOLDING_ETHER:
return ""; // empty string - official 'ETHER' data

case WALLET_HOLDING_TOKEN:
return "token";
}
}

extern BRRlpData // TODO: is this the actual result?
walletGetRawTransaction(BREthereumWallet wallet,
BREthereumTransaction transaction) {
return transactionIsSigned(transaction)
? transactionEncodeRLP(transaction, TRANSACTION_RLP_SIGNED)
: NULL;
}
/*
Expand Down
3 changes: 2 additions & 1 deletion ethereum/BREthereumWallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ walletCreateTransactionDetailed(BREthereumWallet wallet,

extern void
walletSignTransaction(BREthereumWallet wallet,
BREthereumTransaction transaction);
BREthereumTransaction transaction,
const char *paperKey);

/**
* For `transaction`, get the 'signed transaction data' suitable for use in the RPC-JSON Ethereum
Expand Down
Loading

0 comments on commit 95e3fcf

Please sign in to comment.