SyntaxError: sintaxis no válida en web.py con contrato ABI

Todos, estoy atascado con un SyntaxError: sintaxis no válida cada vez que intento ejecutar este script en la variable contract_abi que obtuve del Remix IDE. Actualmente estoy tratando de conectarme con un contrato inteligente en la red de prueba de Ropsten y simplemente llamar a una función de visualización. Aquí está mi código:

import argparse
import sys
import time
import RPi.GPIO as GPIO
from web3 import Web3, HTTPProvider
from chirp import ChirpConnect, CallbackSet, CHIRP_CONNECT_STATE

contract_address = '0xf9bd6f5382f841f8ec9ac1a2b0576c55e45db051'
wallet_private_key = '54485fb890521bbf8345b39dd78aa4f6e02abd9a57e172bc894ded3401d42b07'
wallet_address = '0x5a6e5c4cc373a45ec2c1fe0cf41ff75c6cf930b8'

web3 = Web3(HTTPProvider('https://mainnet.infura.io/v3/a222429a84da4e95bb6d2f16f675d00b')

contract_abi = '''
[
    {
        "constant": true,
        "inputs": [],
        "name": "getKey",
        "outputs": [
            {
                "name": "",
                "type": "string"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [
            {
                "name": "_key",
                "type": "string"
            }
        ],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "constructor"
    }
]
'''

contract_instance = web3.eth.contract(address = contract_address, abi = contract_abi)

class MyCallbacks(CallbackSet):

    def on_state_changed(self, previous_state, current_state):
        """ Called when the SDK's state has changed """
        print("State changed from {} to {}".format(
            CHIRP_CONNECT_STATE.get(previous_state),
            CHIRP_CONNECT_STATE.get(current_state)))

    def on_sending(self, payload):
        """ Called when a chirp has started to be transmitted """
        print('Sending: ' + str(payload))

    def on_sent(self, payload):
        """ Called when the entire chirp has been sent """
        print('Sent data')

    def on_receiving(self):
        """ Called when a chirp frontdoor is detected """
        print('Receiving data')

    def on_received(self, payload):
        """
        Called when an entire chirp has been received.
        Note: A length of 0 indicates a failed decode.
        """
        if len(payload) == 0:
            print('Decode failed!')
        else:
            print('Received:' + str(payload))
            print(contract_instance.functions.getKey().call())    


def main(app_key, app_secret, licence_file,
         input_device, output_device,
         block_size, sample_rate):

    # Initialise ConnectSDK
    sdk = ChirpConnect(app_key, app_secret, licence_file)
    print(str(sdk))
    print(sdk.audio.query_devices())

    # Configure audio
    sdk.audio.input_device = input_device
    sdk.audio.output_device = output_device
    sdk.audio.block_size = block_size
    sdk.sample_rate = sample_rate

    # Set callback functions
    sdk.set_callbacks(MyCallbacks())

    # Generate random payload and send
    payload = sdk.random_payload()
    sdk.start(send=True, receive=True)
    sdk.send(payload)

    try:
        # Process audio streams
        while True:
            time.sleep(0.1)
            sys.stdout.write('.')
            sys.stdout.flush()
    except KeyboardInterrupt:
        print('Exiting')

    sdk.stop()
    sdk.close()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Chirp Connect SDK Example',
        epilog='Sends a random chirp payload, then continuously listens for chirps'
    )
    parser.add_argument('key', help='Chirp application key')
    parser.add_argument('secret', help='Chirp application secret')
    parser.add_argument('-l', help='Path to licence file (optional)')
    parser.add_argument('-i', type=int, default=None, help='Input device index (optional)')
    parser.add_argument('-o', type=int, default=None, help='Output device index (optional)')
    parser.add_argument('-b', type=int, default=0, help='Block size (optional)')
    parser.add_argument('-s', type=int, default=44100, help='Sample rate (optional)')
    args = parser.parse_args()

    main(args.key, args.secret, args.l, args.i, args.o, args.b, args.s)

El contrato inteligente que implementé en Ropsten es este:

pragma solidity ^0.4.19;

contract SimpleTest {

    string key;

    constructor (string _key) {
        key = _key;
    }

    function getKey() public view returns(string) {
        return key;
    }

}

¿Alguien tiene idea de lo que estoy haciendo mal? ¡Gracias de antemano!

Respuestas (1)

A la web3 = ...línea le falta un paréntesis final.