#77 Add token accounts to AccountMeta
This commit is contained in:
parent
5420cec228
commit
5887e5ca8c
|
@ -23,7 +23,7 @@ from sha3 import keccak_256
|
|||
import base58
|
||||
import traceback
|
||||
import threading
|
||||
from .solana_rest_api_tools import EthereumAddress, create_storage_account, evm_loader_id, getLamports, \
|
||||
from .solana_rest_api_tools import EthereumAddress, create_storage_account, evm_loader_id, getTokens, \
|
||||
getAccountInfo, solana_cli, call_signed, solana_url, call_emulated, \
|
||||
Trx, deploy_contract, EthereumError
|
||||
from web3 import Web3
|
||||
|
@ -94,7 +94,8 @@ class EthereumModel:
|
|||
"""
|
||||
eth_acc = EthereumAddress(account)
|
||||
logger.debug('eth_getBalance: %s %s', account, eth_acc)
|
||||
balance = getLamports(self.client, evm_loader_id, eth_acc, self.signer.public_key())
|
||||
balance = getTokens(self.client, evm_loader_id, eth_acc, self.signer.public_key())
|
||||
|
||||
return hex(balance*10**9)
|
||||
|
||||
def eth_getBlockByNumber(self, tag, full):
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from solana.publickey import PublicKey
|
||||
from solana.transaction import AccountMeta, TransactionInstruction, Transaction
|
||||
from solana.sysvar import *
|
||||
from solana.blockhash import Blockhash
|
||||
|
@ -17,7 +18,9 @@ from .eth_proto import Trx
|
|||
from solana.rpc.types import TxOpts
|
||||
import re
|
||||
from solana.rpc.commitment import Commitment, Confirmed
|
||||
from solana.rpc.api import SendTransactionError
|
||||
from solana.rpc.api import Client, SendTransactionError
|
||||
from spl.token.constants import TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
from spl.token.instructions import get_associated_token_address
|
||||
|
||||
from construct import Bytes, Int8ul, Int32ul, Int64ul, Struct as cStruct
|
||||
from solana._layouts.system_instructions import SYSTEM_INSTRUCTIONS_LAYOUT, InstructionType as SystemInstructionType
|
||||
|
@ -40,6 +43,11 @@ keccakprog = "KeccakSecp256k11111111111111111111111111111"
|
|||
rentid = "SysvarRent111111111111111111111111111111111"
|
||||
system = "11111111111111111111111111111111"
|
||||
|
||||
ETH_TOKEN_MINT_ID: PublicKey = PublicKey(
|
||||
os.environ.get("ETH_TOKEN_MINT", "HPsV9Deocecw3GeZv1FkAPNCBRfuVyfw9MMwjwRe1xaU")
|
||||
)
|
||||
|
||||
|
||||
ACCOUNT_INFO_LAYOUT = cStruct(
|
||||
"tag" / Int8ul,
|
||||
"eth_acc" / Bytes(20),
|
||||
|
@ -48,6 +56,7 @@ ACCOUNT_INFO_LAYOUT = cStruct(
|
|||
"code_acc" / Bytes(32),
|
||||
"is_blocked" / Int8ul,
|
||||
"blocked_by" / Bytes(32),
|
||||
"eth_token" / Bytes(32),
|
||||
)
|
||||
|
||||
CODE_INFO_LAYOUT = cStruct(
|
||||
|
@ -96,7 +105,7 @@ def createAccountWithSeed(funding, base, seed, lamports, space, program):
|
|||
seed_str = str(seed, 'utf8')
|
||||
data = SYSTEM_INSTRUCTIONS_LAYOUT.build(
|
||||
dict(
|
||||
instruction_type = SystemInstructionType.CreateAccountWithSeed,
|
||||
instruction_type = SystemInstructionType.CREATE_ACCOUNT_WITH_SEED,
|
||||
args=dict(
|
||||
base=bytes(base),
|
||||
seed=dict(length=len(seed_str), chars=seed_str),
|
||||
|
@ -513,14 +522,15 @@ def create_account_list_by_emulate(acc, client, ethTrx, storage):
|
|||
output_json = call_emulated(ethTrx.toAddress.hex(), sender_ether.hex(), ethTrx.callData.hex())
|
||||
logger.debug("emulator returns: %s", json.dumps(output_json, indent=3))
|
||||
for acc_desc in output_json["accounts"]:
|
||||
|
||||
address = bytes.fromhex(acc_desc["address"][2:])
|
||||
if address == ethTrx.toAddress:
|
||||
(contract_sol, code_sol) = (acc_desc["account"], acc_desc["contract"])
|
||||
(contract_sol, code_sol) = (PublicKey(acc_desc["account"]), PublicKey(acc_desc["contract"]))
|
||||
elif address == sender_ether:
|
||||
sender_sol = (acc_desc["account"])
|
||||
sender_sol = PublicKey(acc_desc["account"])
|
||||
else:
|
||||
add_keys_05.append(AccountMeta(pubkey=acc_desc["account"], is_signer=False, is_writable=acc_desc["writable"]))
|
||||
token_account = get_associated_token_address(PublicKey(acc_desc["account"]), ETH_TOKEN_MINT_ID)
|
||||
add_keys_05.append(AccountMeta(pubkey=token_account, is_signer=False, is_writable=True))
|
||||
if acc_desc["contract"]:
|
||||
add_keys_05.append(AccountMeta(pubkey=acc_desc["contract"], is_signer=False, is_writable=acc_desc["writable"]))
|
||||
if acc_desc["new"]:
|
||||
|
@ -537,11 +547,15 @@ def create_account_list_by_emulate(acc, client, ethTrx, storage):
|
|||
accounts = [
|
||||
AccountMeta(pubkey=storage, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=contract_sol, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=get_associated_token_address(contract_sol, ETH_TOKEN_MINT_ID), is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=code_sol, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=sender_sol, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=get_associated_token_address(sender_sol, ETH_TOKEN_MINT_ID), is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=PublicKey(sysinstruct), is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=evm_loader_id, is_signer=False, is_writable=False),
|
||||
] + add_keys_05 + [
|
||||
AccountMeta(pubkey=ETH_TOKEN_MINT_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=TOKEN_PROGRAM_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=PublicKey(sysvarclock), is_signer=False, is_writable=False),
|
||||
]
|
||||
return (accounts, sender_ether, sender_sol, trx)
|
||||
|
@ -626,8 +640,9 @@ def createEtherAccountTrx(client, ether, evm_loader_id, signer, code_acc=None):
|
|||
if ether.startswith('0x'): ether = ether[2:]
|
||||
else: ether = ether.hex()
|
||||
(sol, nonce) = ether2program(ether, evm_loader_id, signer.public_key())
|
||||
associated_token = get_associated_token_address(PublicKey(sol), ETH_TOKEN_MINT_ID)
|
||||
logger.debug('createEtherAccount: {} {} => {}'.format(ether, nonce, sol))
|
||||
seed = b58encode(bytes.fromhex(ether))
|
||||
logger.debug('associatedTokenAccount: {}'.format(associated_token))
|
||||
base = signer.public_key()
|
||||
data=bytes.fromhex('02000000')+CREATE_ACCOUNT_LAYOUT.build(dict(
|
||||
lamports=10**9,
|
||||
|
@ -642,7 +657,12 @@ def createEtherAccountTrx(client, ether, evm_loader_id, signer, code_acc=None):
|
|||
keys=[
|
||||
AccountMeta(pubkey=base, is_signer=True, is_writable=True),
|
||||
AccountMeta(pubkey=PublicKey(sol), is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=associated_token, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=system, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=ETH_TOKEN_MINT_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=TOKEN_PROGRAM_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=ASSOCIATED_TOKEN_PROGRAM_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=rentid, is_signer=False, is_writable=False),
|
||||
]))
|
||||
else:
|
||||
trx.add(TransactionInstruction(
|
||||
|
@ -651,8 +671,13 @@ def createEtherAccountTrx(client, ether, evm_loader_id, signer, code_acc=None):
|
|||
keys=[
|
||||
AccountMeta(pubkey=base, is_signer=True, is_writable=True),
|
||||
AccountMeta(pubkey=PublicKey(sol), is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=associated_token, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=PublicKey(code_acc), is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=system, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=ETH_TOKEN_MINT_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=TOKEN_PROGRAM_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=ASSOCIATED_TOKEN_PROGRAM_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=rentid, is_signer=False, is_writable=False),
|
||||
]))
|
||||
return (trx, sol)
|
||||
|
||||
|
@ -746,9 +771,13 @@ def deploy_contract(acc, client, ethTrx, storage, steps):
|
|||
accounts = [AccountMeta(pubkey=holder, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=storage, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=contract_sol, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=get_associated_token_address(PublicKey(contract_sol), ETH_TOKEN_MINT_ID), is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=code_sol, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=sender_sol, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=get_associated_token_address(PublicKey(sender_sol), ETH_TOKEN_MINT_ID), is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=evm_loader_id, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=ETH_TOKEN_MINT_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=TOKEN_PROGRAM_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=PublicKey(sysvarclock), is_signer=False, is_writable=False),
|
||||
]
|
||||
|
||||
|
@ -783,6 +812,15 @@ def getLamports(client, evm_loader, eth_acc, base_account):
|
|||
(account, nonce) = ether2program(bytes(eth_acc).hex(), evm_loader, base_account)
|
||||
return int(client.get_balance(account, commitment=Confirmed)['result']['value'])
|
||||
|
||||
def getTokens(client, evm_loader, eth_acc, base_account):
|
||||
(account, nonce) = ether2program(bytes(eth_acc).hex(), evm_loader, base_account)
|
||||
token_account = get_associated_token_address(PublicKey(account), ETH_TOKEN_MINT_ID)
|
||||
|
||||
balance = client.get_token_account_balance(token_account, commitment=Confirmed)
|
||||
if 'error' in balance:
|
||||
return 0
|
||||
|
||||
return int(balance['result']['value']['amount'])
|
||||
|
||||
def make_instruction_data_from_tx(instruction, private_key=None):
|
||||
if isinstance(instruction, dict):
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
|
||||
@@ -33,6 +33,11 @@
|
||||
return types.MemcmpOpts(*args, **kwargs)
|
||||
|
||||
|
||||
|
||||
+class SendTransactionError(Exception):
|
||||
+ def __init__(self, result):
|
||||
+ super().__init__(result['message'])
|
||||
|
@ -21,7 +20,7 @@
|
|||
class Client: # pylint: disable=too-many-public-methods
|
||||
"""Client class."""
|
||||
|
||||
@@ -284,7 +289,7 @@
|
||||
@@ -328,7 +334,7 @@
|
||||
|
||||
return self._provider.make_request(types.RPCMethod("getConfirmedSignaturesForAddress2"), account, opts)
|
||||
|
||||
|
@ -30,7 +29,7 @@
|
|||
"""Returns transaction details for a confirmed transaction.
|
||||
|
||||
:param tx_sig: Transaction signature as base-58 encoded string N encoding attempts to use program-specific
|
||||
@@ -315,7 +320,7 @@
|
||||
@@ -359,7 +365,7 @@
|
||||
'signatures': ['3PtGYH77LhhQqTXP4SmDVJ85hmDieWsgXCUbn14v7gYyVYPjZzygUQhTk3bSTYnfA48vCM1rmWY7zWL3j1EVKmEy']}},
|
||||
'id': 4}
|
||||
""" # noqa: E501 # pylint: disable=line-too-long
|
||||
|
@ -39,7 +38,7 @@
|
|||
|
||||
def get_epoch_info(self, commitment: Commitment = Max) -> types.RPCResponse:
|
||||
"""Returns information about the current epoch.
|
||||
@@ -1039,6 +1044,7 @@
|
||||
@@ -1083,6 +1089,7 @@
|
||||
def __post_send(self, resp: types.RPCResponse, skip_confirm: bool, conf_comm: Commitment) -> types.RPCResponse:
|
||||
if resp.get("error"):
|
||||
self._provider.logger.error(resp.get("error"))
|
||||
|
|
|
@ -4,4 +4,4 @@ pysha3==1.0.2
|
|||
eth-keys==0.3.3
|
||||
rlp==2.0.1
|
||||
web3
|
||||
solana==0.6.5
|
||||
solana==0.10.0
|
||||
|
|
Loading…
Reference in New Issue