Example #1
0
def main():
    # In examples we use addresses which already have funds
    entity1 = Entity.from_hex(
        '6e8339a0c6d51fc58b4365bf2ce18ff2698d2b8c40bb13fcef7e1ba05df18e4b')
    entity2 = Entity.from_hex(
        'e833c747ee0aeae29e6823e7c825d3001638bc30ffe50363f8adf2693c3286f8')

    address1 = Address(entity1)

    # create a second private key pair
    address2 = Address(entity2)

    # build the ledger API
    api = LedgerApi('127.0.0.1', 8000)

    # create the smart contract
    contract = Contract(CONTRACT_TEXT, entity1)

    with track_cost(api.tokens, entity1, "Cost of creation: "):
        api.sync(contract.create(api, entity1, 4000))

    # print the current status of all the tokens
    print('-- BEFORE --')
    print_address_balances(api, contract, [address1, address2])

    # transfer from one to the other using our newly deployed contract
    tok_transfer_amount = 200
    fet_tx_fee = 160
    with track_cost(api.tokens, entity1, "Cost of transfer: "):
        api.sync(
            contract.action(api, 'transfer', fet_tx_fee, entity1, address1,
                            address2, tok_transfer_amount))

    print('-- AFTER --')
    print_address_balances(api, contract, [address1, address2])
Example #2
0
def run(options):
    ENDPOINT = 'fetch/token/transfer'
    HOST = options['host']
    PORT = options['port']

    # create the APIs
    api = LedgerApi(HOST, PORT)

    # Hardcoded private keys
    id1PrivateKey = "d222867ac019aa7e5b5946ee23100b4437d54ec08db8e89f6e459d497b579a03"
    id2PrivateKey = "499f40c1bf13e7716e62431b17ab668fa2688b7c94a011a3aab595477bc68347"

    # Create identities from the private keys
    id1 = Entity.from_hex(id1PrivateKey)
    id2 = Entity.from_hex(id2PrivateKey)

    # Load 1000 tokens to id1
    api.sync(api.tokens.wealth(id1, 1000))

    # signed transaction that transfers 250 FET from id1 to id2. Signed with (r,s)
    orig_tx = 'a1440000c5ab20e3ab845cb4a1d2c3e4c3b08f5ff42a6ff2a71d7697ba8f32c415b77c7f8d850b3ef025b189a2d9bb4a515a84c3673db6d3ef25385d2c8d1e34b06e2de1c0fac08501140000000000000000040bafbc61a08524372f495d9dee08adbc39824e980506947091395cece16636ddc094b9d409d5b34ef0bbd9c99c5caf21fc373802472cf96a8a280f84e833f992402192a0a125d551b60800d441cb3483cd36573c22a73f22563d6dd7b27e677b98ba4e2f77596888839a3c6f2439c97949ea28923f168d360a6d155c2be79570af'
    # signed Malicious transaction of the previous transaction. Signed with (r,n-s)
    mal_tx = 'a1440000c5ab20e3ab845cb4a1d2c3e4c3b08f5ff42a6ff2a71d7697ba8f32c415b77c7f8d850b3ef025b189a2d9bb4a515a84c3673db6d3ef25385d2c8d1e34b06e2de1c0fac08501140000000000000000040bafbc61a08524372f495d9dee08adbc39824e980506947091395cece16636ddc094b9d409d5b34ef0bbd9c99c5caf21fc373802472cf96a8a280f84e833f99240f1a0311cc9b42edaa41d537e3d1f9d54ac159504276c27be2973cea85c8e8a17148a2b1dc3e188f911c6b05f163d95b964ae594a347870973e59b3c93d35b895'

    # Creating jsons for the above mentioned transactions
    legit_trans = submit_json_transaction(
        host=HOST,
        port=PORT,
        tx_data=dict(ver="1.2",
                     data=base64.b64encode(
                         binascii.unhexlify(orig_tx)).decode()),
        endpoint=ENDPOINT)
    mal_trans = submit_json_transaction(
        host=HOST,
        port=PORT,
        tx_data=dict(ver="1.2",
                     data=base64.b64encode(
                         binascii.unhexlify(mal_tx)).decode()),
        endpoint=ENDPOINT)

    # Sending the transactions to the ledger
    assert legit_trans == mal_trans, "Malleable transactions have different transaction hash"
    api.sync([legit_trans, mal_trans])

    # If transaction malleability is feasible, id2 should have 500 FET.
    # If balance of id2 is more than 250 raise an exception
    assert api.tokens.balance(
        id2) == 250, "Vulnerable to transaction malleability attack"
Example #3
0
def run(options, benefactor):
    ENDPOINT = 'fetch/token/transfer'
    HOST = options['host']
    PORT = options['port']

    # create the APIs
    api = LedgerApi(HOST, PORT)

    # Hardcoded private keys
    id1PrivateKey = "d222867ac019aa7e5b5946ee23100b4437d54ec08db8e89f6e459d497b579a03"
    id2PrivateKey = "499f40c1bf13e7716e62431b17ab668fa2688b7c94a011a3aab595477bc68347"

    # Create identities from the private keys
    id1 = Entity.from_hex(id1PrivateKey)
    id2 = Entity.from_hex(id2PrivateKey)

    # Load 100000 tokens to id1
    api.sync(api.tokens.transfer(benefactor, id1, 100000, 1000))

    # signed transaction that transfers 2500 FET from id1 to id2. Signed with (r,s) Fees are 1000
    orig_tx = 'a1640000c5ab20e3ab845cb4a1d2c3e4c3b08f5ff42a6ff2a71d7697ba8f32c415b77c7f8d850b3ef025b189a2d9bb4a515a84c3673db6d3ef25385d2c8d1e34b06e2de1c109c46501c103e8565596cd793442c5040bafbc61a08524372f495d9dee08adbc39824e980506947091395cece16636ddc094b9d409d5b34ef0bbd9c99c5caf21fc373802472cf96a8a280f84e833f99240f1c72a58927153d6fdc19f178f69c5b02db29f33541e2b946c78a54ce693c7c81082f22531b85a1707cf290f73fddd2df88681084b0cc7aff38e977215ae5899'
    # signed Malicious transaction of the previous transaction. Signed with (r,n-s)
    mal_tx = 'a1640000c5ab20e3ab845cb4a1d2c3e4c3b08f5ff42a6ff2a71d7697ba8f32c415b77c7f8d850b3ef025b189a2d9bb4a515a84c3673db6d3ef25385d2c8d1e34b06e2de1c109c46501c103e8565596cd793442c5040bafbc61a08524372f495d9dee08adbc39824e980506947091395cece16636ddc094b9d409d5b34ef0bbd9c99c5caf21fc373802472cf96a8a280f84e833f99240cb13a3a05600cd45c7abe860515801941d6eef439e697ab31015543b515e5b85495f2a3f95a352747eda205cc70e0bca7a4d8b1240dfbd43f3a047a1faad30bd'

    # Creating jsons for the above mentioned transactions
    legit_trans = submit_json_transaction(
        host=HOST,
        port=PORT,
        tx_data=dict(ver="1.2",
                     data=base64.b64encode(
                         binascii.unhexlify(orig_tx)).decode()),
        endpoint=ENDPOINT)
    mal_trans = submit_json_transaction(
        host=HOST,
        port=PORT,
        tx_data=dict(ver="1.2",
                     data=base64.b64encode(
                         binascii.unhexlify(mal_tx)).decode()),
        endpoint=ENDPOINT)

    # Sending the transactions to the ledger
    assert legit_trans == mal_trans, "Malleable transactions have different transaction hash"
    api.sync([legit_trans, mal_trans])

    # If transaction malleability is feasible, id2 should have 500 FET.
    # If balance of id2 is more than 250 raise an exception
    assert api.tokens.balance(
        id2) == 2500, "Vulnerable to transaction malleability attack"
def generate_fetchai_wealth(arguments: argparse.Namespace) -> None:
    """
    Generate tokens to be able to make a transaction.

    :param arguments: the arguments
    :return: None
    """
    try:
        api = LedgerApi(arguments.addr, arguments.port)
    except Exception:
        logging.info("Couldn't connect! Please check your add and port.")
        sys.exit(1)

    try:
        if arguments.private_key is None or arguments.private_key == "":
            raise ValueError
    except ValueError:
        logging.error("Please provide a private key. --private-key .... ")
        sys.exit(1)

    logging.info("Waiting for token wealth generation...")
    entity_to_generate_wealth = Entity.from_hex(
        Path(arguments.private_key).read_text())
    api.sync(api.tokens.wealth(entity_to_generate_wealth, arguments.amount))
    address = Address(entity_to_generate_wealth)
    balance = api.tokens.balance(address)
    logging.info('The new balance of the address {} is : {} FET'.format(
        address, balance))
Example #5
0
def main():
    # create the API
    api = LedgerApi('127.0.0.1', 8000)

    # create an entity from a private key stored in hex
    entity = Entity.from_hex(
        '6e8339a0c6d51fc58b4365bf2ce18ff2698d2b8c40bb13fcef7e1ba05df18e4b')

    # create the contract on the ledger
    synergetic_contract = Contract(CONTRACT_TEXT, entity)
    print('Creating contract..')
    api.sync(api.contracts.create(entity, synergetic_contract, 4096))

    # create a whole series of random data to submit to the DAG
    random_ints = [random.randint(0, 200) for _ in range(10)]
    fee = 100000000
    api.sync(
        [api.contracts.submit_data(entity, synergetic_contract.digest, synergetic_contract.address, fee, value=value) \
         for value in random_ints])
    print('Data submitted.')

    print('Waiting...')
    api.wait_for_blocks(10)

    print('Issuing query...')
    result = synergetic_contract.query(api, 'query_result')
    print('Query result:', result)
Example #6
0
def main():
    entity = Entity.from_hex(
        '6e8339a0c6d51fc58b4365bf2ce18ff2698d2b8c40bb13fcef7e1ba05df18e4b')
    address = Address(entity)
    print('Address:', address)

    # create the APIs
    api = LedgerApi(HOST, PORT)

    # Display balance before
    print('Balance:', api.tokens.balance(entity))

    print('Stake..:', api.tokens.stake(entity))

    # submit and wait for the transfer to be complete
    print('Submitting stake request...')
    api.sync(api.tokens.add_stake(entity, 1000, 50))

    while True:
        print('Balance............:', api.tokens.balance(entity))
        print('Stake..............:', api.tokens.stake(entity))
        print('Stake on cooldown..:', api.tokens.stake_cooldown(entity))

        # De-stake half of the staked balance
        to_destake = int(api.tokens.stake(entity) / 2)
        api.sync(api.tokens.de_stake(entity, to_destake, 500))

        # Collect cooled down stakes
        api.sync(api.tokens.collect_stake(entity, 500))
        time.sleep(1)
Example #7
0
def main():
    # create the APIs
    api = LedgerApi(HOST, PORT)

    # generate identities from hex private keys,
    identity1 = Entity.from_hex('6e8339a0c6d51fc58b4365bf2ce18ff2698d2b8c40bb13fcef7e1ba05df18e4b')
    identity2 = Entity.from_hex('e833c747ee0aeae29e6823e7c825d3001638bc30ffe50363f8adf2693c3286f8')

    print('Balance 1 Before:', api.tokens.balance(identity1))
    print('Balance 2 Before:', api.tokens.balance(identity2))

    # submit and wait for the transfer to be complete
    print('Submitting transfer...')
    api.sync(api.tokens.transfer(identity1, identity2, 250, 20))

    print('Balance 1:', api.tokens.balance(identity1))
    print('Balance 2:', api.tokens.balance(identity2))
Example #8
0
def _try_validate_fet_private_key_path(private_key_path: str) -> None:
    """
    Try to validate a private key.

    :param private_key_path: the path to the private key.
    :return: None
    :raises: an exception if the private key is invalid.
    """
    try:
        with open(private_key_path, "r") as key:
            data = key.read()
            Entity.from_hex(data)
    except Exception as e:
        logger.error(
            "This is not a valid private key file: '{}'\n Exception: '{}'".
            format(private_key_path, e))
        sys.exit(1)
Example #9
0
def main():
    api = LedgerApi(HOST, PORT)
    # in our examples we use Addresses with funds, which we load from hex-encoded private keys.
    identity1 = Entity.from_hex('6e8339a0c6d51fc58b4365bf2ce18ff2698d2b8c40bb13fcef7e1ba05df18e4b')
    identity2 = Entity.from_hex('e833c747ee0aeae29e6823e7c825d3001638bc30ffe50363f8adf2693c3286f8')

    # we make a Transfer which returns a transaction id.
    tx = api.tokens.transfer(identity1, identity2, 2500, 20)

    # wait for the transaction to complete so that the information is 100% present
    api.sync(tx)

    # we Verify that the transaction is the submitted transaction is the sent transaction
    # TxContents object (below contents variable) contains all properties sent to ledger in transaction API call
    contents = api.tx.contents(tx)

    # below we access a subset of the properties of our TxContents object
    valid_until = contents.valid_until
    valid_from = contents.valid_from
    from_address = contents.from_address
    transfers = contents.transfers

    # iterate over the transfers in the transaction, which is singular in this instance
    for to_address, amount in transfers.items():
        print(
            "\nThe submitted transaction is from Address: {}\nto Address: {} \nof amount: {}\nand is valid from (block number): {} \nand valid until (block number): {}".format(
                str(from_address), to_address, amount, valid_from, valid_until))

    nonexistent_entity = Entity()

    # check the amount being transferred to a particular address; zero in the below instance
    amount = contents.transfers_to(nonexistent_entity)

    if amount == 0:
        print("\nAs expected, nothing is being transferred to Address: ", str(Address(nonexistent_entity)))
    else:
        print("\nExample failure: nothing should be transferred to Address: ", str(Address(nonexistent_entity)))

    # check the status of a transaction. This is an alternative to calling the LedgerApi's sync method, which itself polls the below status endpoint
    status = api.tx.status(tx)

    print('\nCurrent Status is :', status.status)
Example #10
0
    def __init__(self, *args, **kwargs):
        super(RiderAgent, self).__init__(*args, **kwargs)

        riders = [ '904f302f980617d5f40219337ef826cdf64992e577676cdd83295f189af82ff4',
                '03f807bbf02cf849145fc51d7dd4438559dc4756a3b2321bbdf42e8f7910a3df',
                'dfe06a3baa93ad1d2f248317c601f710821cc1916e09d7c6e261f432563e50f1',
                'a92e7c9a1c091bb7bc70874da36fdc44a8217577758a061e008344bd402a6118',
                '672ebe1ef50a3c49532fe2118686d7025048de51e4f77ed8d0880cd52efe80a7']
        self._entity = Entity.from_hex(riders[int(sys.argv[1])-1])
        self._address = Address(self._entity)
        self._api = LedgerApi('127.0.0.1', 8000)
        self._api.sync(self._api.tokens.wealth(self._entity, 5000000))
Example #11
0
    def load_private_key_from_path(cls, file_name: str) -> Entity:
        """
        Load a private key in hex format from a file.

        :param file_name: the path to the hex file.

        :return: the Entity.
        """
        path = Path(file_name)
        with path.open() as key:
            data = key.read()
            entity = Entity.from_hex(data)
        return entity
def main():
    # create our first private key pair
    entity1 = Entity.from_hex(
        'd5f10ad865fff147ae7fcfdc98b755452a27a345975c8b9b3433ff16f23495fb')

    # build the ledger API
    api = LedgerApi('127.0.0.1', 8100)

    # create the smart contract
    contract = Contract(CONTRACT_TEXT, entity1)

    # deploy the contract to the network
    api.sync(api.contracts.create(entity1, contract, 1000000000))

    # update the graph with a new model
    fet_tx_fee = 100000000
    with open(GRAPH_FILE_NAME, mode='rb') as file:
        print("reading in graph file...")
        rfile = file.read()

        print("encoding to base64 string...")
        b64obj = base64.b64encode(rfile)
        obj = b64obj.decode()

        print("updating smart contract graph...")
        api.sync(
            contract.action(api, 'updateGraph', fet_tx_fee, [entity1], obj))

    print("finished updating smart contract graph")

    # set one real example input data set
    fet_tx_fee = 100000000
    api.sync(
        contract.action(api, 'setHistorics', fet_tx_fee, [entity1],
                        EXAMPLE_INPUT_HISTORICS))

    current_historics = contract.query(api, 'getHistorics')
    print("current historics: " + current_historics)

    # make a prediction
    current_prediction = contract.query(api, 'makePrediction')
    print("current prediction: " + current_prediction)
Example #13
0
    def _load_private_key_from_path(self, file_name) -> Entity:
        """
        Load a private key in hex format from a file.

        :param file_name: the path to the hex file.

        :return: the Entity.
        """
        path = Path(file_name)
        try:
            if path.is_file():
                with open(path, "r") as key:
                    data = key.read()
                    entity = Entity.from_hex(data)

            else:
                entity = self._generate_private_key()

            return entity
        except IOError as e:  # pragma: no cover
            logger.exception(str(e))
Example #14
0
def main():
    # create the APIs
    api = LedgerApi(HOST, PORT)

    # generate an identity from a known key, which contains funds.
    multi_sig_identity = Entity.from_hex(
        "6e8339a0c6d51fc58b4365bf2ce18ff2698d2b8c40bb13fcef7e1ba05df18e4b")
    # generate a board to control multi-sig account, with variable voting weights.
    # we use keys for accounts which already have funds.
    board = []
    board.append(
        Entity.from_hex(
            "e833c747ee0aeae29e6823e7c825d3001638bc30ffe50363f8adf2693c3286f8")
    )
    board.append(
        Entity.from_hex(
            "4083a476c4872f25cb40839ac8d994924bcef12d83e2ba4bd3ed6c9705959860")
    )
    board.append(
        Entity.from_hex(
            "20293422c4b5faefba3422ed436427f2d37f310673681e98ac8637b04e756de3")
    )
    board.append(
        Entity.from_hex(
            "d5f10ad865fff147ae7fcfdc98b755452a27a345975c8b9b3433ff16f23495fb")
    )
    voting_weights = {
        board[0]: 1,
        board[1]: 1,
        board[2]: 1,
        board[3]: 2,
    }
    # generate another entity as a target for transfers
    other_identity = Entity.from_hex(
        "e833c747ee0aeae29e6823e7c825d3001638bc30ffe50363f8adf2693c3286f8")

    print('Original balance of multi_sig_identity:',
          api.tokens.balance(multi_sig_identity))

    # transfers can happen normally without a deed
    print('\nSubmitting pre-deed transfer with original signature...')
    api.sync(api.tokens.transfer(multi_sig_identity, other_identity, 250, 20))

    print('Balance 1:', api.tokens.balance(multi_sig_identity))
    print('Balance 2:', api.tokens.balance(other_identity))

    # submit the original deed
    print("\nCreating deed...")
    deed = Deed()
    for sig, weight in voting_weights.items():
        deed.set_signee(sig, weight)
    # set our initial voting thresholds
    deed.set_operation(Operation.transfer, 2)
    deed.set_operation(Operation.amend, 4)

    api.sync(api.tokens.deed(multi_sig_identity, deed, 6000))

    # original address can no longer validate transfers
    print("\nTransfer with original signature should fail...")
    try:
        api.sync(
            api.tokens.transfer(multi_sig_identity, other_identity, 250, 20))
    except RuntimeError as e:
        print("Transaction failed as expected")
    else:
        print("Transaction succeeded, it shouldn't have")

    # sufficient voting power required to sign transfers
    print("\nSubmitting transfer with two signatures with total 2 votes...")
    print_signing_votes(voting_weights, board[:2])

    # since we now want to create a transaction which has only been signed by a subset of the board, we must use
    # the factory interface in order to build out the transaction we are after
    tx = TokenTxFactory.transfer(multi_sig_identity, other_identity, 250, 20,
                                 board[:2])
    tx.valid_until = api.tokens.current_block_number() + 100
    # the signatories to sign the transaction
    for signatory in board[:2]:
        tx.sign(signatory)

    api.sync(api.submit_signed_tx(tx))

    print('Balance 1:', api.tokens.balance(multi_sig_identity))
    print('Balance 2:', api.tokens.balance(other_identity))

    # some entities may have more voting power
    print("\nSubmitting transfer with single signature with 2 votes...")
    print_signing_votes(voting_weights, board[3])

    tx = TokenTxFactory.transfer(multi_sig_identity, other_identity, 250, 20,
                                 [board[3]])
    tx.valid_until = api.tokens.current_block_number() + 100
    tx.sign(board[3])
    api.sync(api.submit_signed_tx(tx))

    print('Balance 1:', api.tokens.balance(multi_sig_identity))
    print('Balance 2:', api.tokens.balance(other_identity))

    # amend the deed
    print("\nAmending deed to increase transfer threshold to 3 votes...")
    deed.set_operation(Operation.transfer, 3)
    tx = TokenTxFactory.deed(multi_sig_identity, deed, 400, board)
    tx.valid_until = api.tokens.current_block_number() + 100
    for member in board:
        tx.sign(member)
    api.sync(api.submit_signed_tx(tx))

    # single member no longer has enough voting power
    print("\nSingle member transfer with 2 votes should no longer succeed...")
    try:
        print_signing_votes(voting_weights, board[3])

        tx = TokenTxFactory.transfer(multi_sig_identity, other_identity, 250,
                                     20, [board[3]])
        tx.valid_until = api.tokens.current_block_number() + 100
        tx.sign(board[3])
        api.sync(api.submit_signed_tx(tx))

    except RuntimeError as e:
        print("Transaction failed as expected")
    else:
        print("Transaction succeeded, it shouldn't have")

    # correct number of signatory votes
    print("\nSuccesful transaction with sufficient voting weight...")
    print_signing_votes(voting_weights, board[1:])

    tx = TokenTxFactory.transfer(multi_sig_identity, other_identity, 250, 20,
                                 board[1:])
    tx.valid_until = api.tokens.current_block_number() + 100
    for member in board[1:]:
        tx.sign(member)
    api.sync(api.submit_signed_tx(tx))

    print('Balance 1:', api.tokens.balance(multi_sig_identity))
    print('Balance 2:', api.tokens.balance(other_identity))

    # warning: if no amend threshold is set, future amendments are impossible
    print("\nAmending deed to remove threshold...")
    deed.remove_operation(Operation.amend)
    deed.require_amend = False

    tx = TokenTxFactory.deed(multi_sig_identity, deed, 400, board)
    tx.valid_until = api.tokens.current_block_number() + 100
    for member in board:
        tx.sign(member)
    api.sync(api.submit_signed_tx(tx))

    deed.set_operation(Operation.amend, 1)
    print("\nExpecting further amendment to fail...")
    try:
        tx = TokenTxFactory.deed(multi_sig_identity, deed, 400, board)
        tx.valid_until = api.tokens.current_block_number() + 100
        for member in board:
            tx.sign(member)
        api.sync(api.submit_signed_tx(tx))
    except RuntimeError as e:
        print("Transaction failed as expected")
    else:
        print("Transaction succeeded, it shouldn't have")
Example #15
0
from fetchai.ledger.api import LedgerApi
from fetchai.ledger.contract import SmartContract
from fetchai.ledger.crypto import Entity, Address
import time

contract_owner = Entity.from_hex(
    'c25ace8a7a485b396f30e4a0332d0d18fd2e462b3f1404f85a1b7bcac4b4b19d')
contract_owner_address = Address(
    contract_owner)  # atsREugsanXS828FnTvmLM9vCkBsWnDgushDH9YjEgsdBuRGv
with open("./cbns_token.etch", "r") as fb:
    contract_source = fb.read()
api = LedgerApi('127.0.0.1', 8000)
api.sync(api.tokens.wealth(contract_owner, 5000000))
contract = SmartContract(contract_source)
api.sync(api.contracts.create(contract_owner, contract, 2456766))

time.sleep(10)
print('Deployed contract address:', Address(contract.digest))

print('my balance:',
      contract.query(api, 'balanceOf', owner=contract_owner_address))
Example #16
0
    def __init__(self, *args, **kwargs):
        super(ChargerAgent, self).__init__(*args, **kwargs)

        self._entity = Entity.from_hex(sys.argv[5])
        self._address = Address(self._entity)
Example #17
0
    def on_message(self, msg_id: int, dialogue_id: int, origin: str, content: bytes):
        """Extract and print data from incoming (simple) messages."""

        # PLACE HOLDER TO SIGN AND SUBMIT TRANSACTION
        transaction = json.loads(content.decode("utf-8"))
        charge_station_address = Address(binascii.unhexlify(transaction['address']))

        print("Received contract from {0}".format(origin))
        print("READY TO SUBMIT:", origin, "(", charge_station_address, ") price:", transaction['value'], "bonus:", transaction['bonus'])

        #self._api.sync(self._contract.action(self._api, 'transfer', 40, [self._entity], self._address, charge_station_address, transaction['value']))
        self._api.sync(self._api.contracts.action(contract_addr, contract_owner, 'transfer', 40, [self._entity], self._address, charge_station_address, transaction['value']))

        #time.sleep(10)

        #print(self._contract.query(self._api, 'balanceOf', owner=charge_station_address))
        #print(self._api.contracts.query(contract_addr, contract_owner, 'balanceOf', owner=charge_station_address))
        #print(self._api.contracts.query(contract_addr, contract_owner, 'balanceOf', owner=self._address))

        self._api.sync(self._api.contracts.action(Address('QguxAD9FTj2MTnvNbdr15MGPMftXW8qdcewa4X96JEx2SU6hg'), contract_owner, 'transfer', 40, [Entity.from_hex('c25ace8a7a485b396f30e4a0332d0d18fd2e462b3f1404f85a1b7bcac4b4b19d')], contract_owner, self._address, transaction['value'] + transaction['bonus']))

        self.stop()
from fetchai.ledger.serialisation.transaction import encode_payload

from fetchai.ledger.bitvector import BitVector
from fetchai.ledger.crypto import Entity, Identity
from fetchai.ledger.serialisation import encode_transaction, decode_transaction, bytearray, sha256_hash
from fetchai.ledger.transaction import Transaction

_PRIVATE_KEYS = (
    '1411d53f88e736eac7872430dbe5b55ac28c17a3e648c388e0bd1b161ab04427',
    '3436c184890d498b25bc2b5cb0afb6bad67379ebd778eae1de40b6e0f0763825',
    '4a56a19355f934174f6388b3c80598abb151af79c23d5a7af45a13357fb71253',
    'f9d67ec139eb7a1cb1f627357995847392035c1e633e8530de5ab5d04c6e9c33',
    '80f0e1c69e5f1216f32647c20d744c358e0894ebc855998159017a5acda208ba',
)

ENTITIES = [Entity.from_hex(x) for x in _PRIVATE_KEYS]
IDENTITIES = [Identity(x) for x in ENTITIES]


def _calculate_integer_stream_size(length: int) -> int:
    if length < 0x80:
        return 1
    elif length < 0x100:
        return 2
    elif length < 0x1000:
        return 4
    else:
        return 8


class TransactionSerialisation(unittest.TestCase):
Example #19
0
def main():
    # create the APIs
    api = LedgerApi(HOST, PORT)

    # we generate an identity from a known key, which contains funds.
    multi_sig_identity = Entity.from_hex(
        "6e8339a0c6d51fc58b4365bf2ce18ff2698d2b8c40bb13fcef7e1ba05df18e4b")

    # generate a board to control multi-sig account, with variable voting weights
    board = [
        Entity.from_hex(
            "e833c747ee0aeae29e6823e7c825d3001638bc30ffe50363f8adf2693c3286f8"
        ),
        Entity.from_hex(
            "4083a476c4872f25cb40839ac8d994924bcef12d83e2ba4bd3ed6c9705959860"
        ),
        Entity.from_hex(
            "20293422c4b5faefba3422ed436427f2d37f310673681e98ac8637b04e756de3"
        ),
        Entity.from_hex(
            "d5f10ad865fff147ae7fcfdc98b755452a27a345975c8b9b3433ff16f23495fb"
        ),
    ]

    voting_weights = {
        board[0]: 1,
        board[1]: 1,
        board[2]: 1,
        board[3]: 2,
    }

    # generate another entity as a target for transfers
    other_identity = Entity.from_hex(
        "7da0e3fa62a916238decd4f54d43301c809595d66dd469f82f29e076752b155c")

    # submit deed
    print("\nCreating deed...")
    deed = Deed()
    for sig, weight in voting_weights.items():
        deed.set_signee(sig, weight)
    deed.set_operation(Operation.amend, 4)
    deed.set_operation(Operation.transfer, 3)

    api.sync(api.tokens.deed(multi_sig_identity, deed, 500))

    # display balance before
    print("\nBefore remote-multisig transfer")
    print('Balance 1:', api.tokens.balance(multi_sig_identity))
    print('Balance 2:', api.tokens.balance(other_identity))
    print()

    # scatter/gather example
    print("Generating transaction and distributing to signers...")

    # add intended signers to transaction
    ref_tx = TokenTxFactory.transfer(multi_sig_identity,
                                     other_identity,
                                     250,
                                     20,
                                     signatories=board)
    api.set_validity_period(ref_tx)

    # make a reference payload that can be used in this script for validation
    reference_payload = ref_tx.encode_payload()

    # have signers individually sign transaction
    signed_txs = []
    for signer in board:
        # signer builds their own transaction to compare to note that each of the signers will need to agree on all
        # parts of the message including the validity period and the counter
        signer_tx = TokenTxFactory.transfer(multi_sig_identity,
                                            other_identity,
                                            250,
                                            20,
                                            signatories=board)
        signer_tx.counter = ref_tx.counter
        signer_tx.valid_until = ref_tx.valid_until
        signer_tx.valid_from = ref_tx.valid_from

        # sanity check each of the signers payload should match the reference payload
        assert signer_tx.encode_payload() == reference_payload

        # signers locally sign there version of the transaction
        signer_tx.sign(signer)

        # simulate distribution of signed partial transactions
        signed_txs.append(signer_tx.encode_partial())

    # gather and encode final transaction - this step in theory can be done by all the signers provided they are
    # received all the signature shares
    print("Gathering and combining signed transactions...")
    partial_txs = [Transaction.decode_partial(s)[1] for s in signed_txs]

    # merge them together into one fully signed transaction
    success, tx = Transaction.merge(partial_txs)
    assert success  # this indicates that all the signatures have been merged and that the transaction now validates

    # submit the transaction
    api.sync(api.submit_signed_tx(tx))

    print("\nAfter remote multisig-transfer")
    print('Balance 1:', api.tokens.balance(multi_sig_identity))
    print('Balance 2:', api.tokens.balance(other_identity))

    # round-robin example
    print("\nGenerating transaction and sending down the line of signers...")

    # create the basis for the transaction
    tx = TokenTxFactory.transfer(multi_sig_identity,
                                 other_identity,
                                 250,
                                 20,
                                 signatories=board)
    api.set_validity_period(tx)

    # serialize and send to be signed
    tx_payload = tx.encode_payload()

    # have signers individually sign transaction and pass on to next signer
    for signer in board:
        # build the target transaction
        signer_tx = Transaction.decode_payload(tx_payload)

        # Signer decodes payload to inspect transaction
        signer_tx.sign(signer)

        # ensure that when we merge the signers signature into the payload that it is correct
        assert tx.merge_signatures(signer_tx)

    # once all the partial signatures have been merged then it makes sense
    print("Collecting final signed transaction...")
    assert tx.is_valid()
    api.sync(api.submit_signed_tx(tx))

    print("\nAfter remote multisig-transfer")
    print('Balance 1:', api.tokens.balance(multi_sig_identity))
    print('Balance 2:', api.tokens.balance(other_identity))