Esempio n. 1
0
File: main.py Progetto: Gricha/orisi
def pricecheck_create(args):
  if len(args)<5:
    print "USAGE: `%s pricecheck_create <pubkey_once> <locktime_minutes> <return_address_if_greater> <return_address_if_smaller> <value>`" % START_COMMAND
    print "- run `%s main` to obtain pubkey_once" % START_COMMAND
    print "- keep in mind that this is alpha, don't expect oracles to run properly for any extended periods of time"
    return

  btc = BitcoinClient()

  request = {}
  client_pubkey = args[0]
  request['locktime'] = time.time() + int(args[1])*60
  request['return_if_greater'] = args[2]
  request['return_if_lesser'] = args[3]
  request['price'] = float(args[4])

  print "fetching charter url" # hopefully it didn't check between running main1 and main2
  charter = fetch_charter(CHARTER_URL)

  oracle_pubkeys = []
  oracle_fees = {}
  oracle_bms = []

  for o in charter['nodes']:
    oracle_pubkeys.append(o['pubkey'])
    oracle_fees[o['address']] = o['fee']
    oracle_bms.append(o['bm'])

  oracle_fees[charter['org_address']] = charter['org_fee']

  min_sigs = int(ceil(float(len(oracle_pubkeys))/2))

  key_list = [client_pubkey] + oracle_pubkeys

  response = btc.create_multisig_address(min_sigs, key_list)
  msig_addr = response['address'] # we're using this as an identificator
  redeemScript = response['redeemScript']

  request['message_id'] = "%s-%s" % (msig_addr, str(randrange(1000000000,9000000000)))
  request['pubkey_list'] = key_list

  request['miners_fee_satoshi'] = MINERS_FEE

  print "fetching transactions incoming to %s ..." % msig_addr

  # for production purposes you might want to fetch the data using bitcoind, but that's expensive
  address_json = liburl_wrapper.safe_read("https://blockchain.info/address/%s?format=json" % msig_addr, timeout_time=10)
  try:
    address_history = json.loads(address_json)
  except:
    print "blockchain.info problem"
    print address_json
    return

  prevtxs = []
  sum_satoshi = 0

  for tx in address_history['txs']:
    outputs = []
    if 'out' in tx:
      outputs = outputs + tx['out']
    if 'outputs' in tx:
      outputs = outputs + tx['outputs']

    for vout in tx['out']:
      print vout
      if vout['addr'] == msig_addr:
        prevtx = {
          'scriptPubKey' : vout['script'],
          'vout': vout['n'],
          'txid': tx['hash'],
          'redeemScript': redeemScript,
        }
        sum_satoshi += vout['value']
        prevtxs.append(prevtx)

  if len(prevtxs) == 0:
    print "ERROR: couldn't find transactions sending money to %s" % msig_addr
    return

  request['prevtxs'] = prevtxs
  request['outputs'] = oracle_fees

  request["req_sigs"] = min_sigs
  request['operation'] = 'pricecheck_create'
  request['sum_satoshi'] = sum_satoshi

  bm = BitmessageClient()
  print "sending: %r" % json.dumps(request)
  print bm.chan_address

  request_content = json.dumps(request)

  print bm.send_message(bm.chan_address, request['operation'], request_content)
Esempio n. 2
0
File: main.py Progetto: Gricha/orisi
def main2(args):
  if len(args)<3:
    print "USAGE: `%s main2 <pubkey_once> <locktime_minutes> <return_address>`" % START_COMMAND
    print "- run `%s main` to obtain pubkey_once" % START_COMMAND
    print "- keep in mind that this is alpha, don't expect oracles to run properly for any extended periods of time"
    return

  btc = BitcoinClient()

  request = {}
  client_pubkey = args[0]
  request['locktime'] = time.time() + int(args[1])*60
  request['return_address'] = args[2]

  print "fetching charter url" # hopefully it didn't check between running main1 and main2
  charter = fetch_charter(CHARTER_URL)

  oracle_pubkeys = []
  oracle_fees = {}
  oracle_bms = []

  for o in charter['nodes']:
    oracle_pubkeys.append(o['pubkey'])
    oracle_fees[o['address']] = o['fee']
    oracle_bms.append(o['bm'])

  oracle_fees[charter['org_address']] = charter['org_fee']

  min_sigs = int(ceil(float(len(oracle_pubkeys))/2))

  key_list = [client_pubkey] + oracle_pubkeys

  response = btc.create_multisig_address(min_sigs, key_list)
  msig_addr = response['address'] # we're using this as an identificator
  redeemScript = response['redeemScript']

  request['message_id'] = "%s-%s" % (msig_addr, str(randrange(1000000000,9000000000)))
  request['pubkey_list'] = key_list

  request['miners_fee_satoshi'] = MINERS_FEE

  print "fetching transactions incoming to %s ..." % msig_addr

  # for production purposes you might want to fetch the data using bitcoind, but that's expensive
  address_json = liburl_wrapper.safe_read("https://blockchain.info/address/%s?format=json" % msig_addr, timeout_time=10)
  try:
    address_history = json.loads(address_json)
  except:
    print "blockchain.info problem"
    print address_json
    return

  prevtxs = []
  sum_satoshi = 0

  for tx in address_history['txs']:
    outputs = []
    if 'out' in tx:
      outputs = outputs + tx['out']
    if 'outputs' in tx:
      outputs = outputs + tx['outputs']

    for vout in tx['out']:
      print vout
      if vout['addr'] == msig_addr:
        prevtx = {
          'scriptPubKey' : vout['script'],
          'vout': vout['n'],
          'txid': tx['hash'],
          'redeemScript': redeemScript,
        }
        sum_satoshi += vout['value']
        prevtxs.append(prevtx)

  if len(prevtxs) == 0:
    print "ERROR: couldn't find transactions sending money to %s" % msig_addr
    return

  request['prevtxs'] = prevtxs
  request['outputs'] = oracle_fees

  request["req_sigs"] = min_sigs
  request['operation'] = 'timelock_create'
  request['sum_satoshi'] = sum_satoshi

  bm = BitmessageClient()
  print "sending: %r" % json.dumps(request)
  print bm.chan_address

  request_content = json.dumps(request)

  print bm.send_message(bm.chan_address, request['operation'], request_content)

  print ""
  print "Gathering oracle responses. It may take BitMessage 30-60 seconds to deliver a message one way."
  print "Although we've seen delays up to half an hour, especially if BitMessage client was just launched."
  print ""


  oracles_confirmed = 0
  while oracle_bms:
    messages = bm.get_unread_messages()
    print "oracles confirmed: {}".format(oracles_confirmed)
    for msg in messages:
      if msg.from_address in oracle_bms:
        try:
          content = json.loads(msg.message)
        except:
          print msg.message
          print 'failed decoding message'
          continue

        if 'in_reply_to' not in content:
          continue

        if content['in_reply_to'] == request['message_id']:
            print "[%r][%r] %r" % (msg.subject, msg.from_address, msg.message)
            print ""
            oracle_bms.remove(msg.from_address)

    if oracle_bms: #if still awaiting replies from some oracles
      time.sleep(10)
Esempio n. 3
0
def main2(args):
    if len(args) < 3:
        print "USAGE: `%s main2 <pubkey_once> <locktime_minutes> <return_address>`" % START_COMMAND
        print "- run `%s main` to obtain pubkey_once" % START_COMMAND
        print "- keep in mind that this is alpha, don't expect oracles to run properly for any extended periods of time"
        return

    btc = BitcoinClient()

    request = {}
    client_pubkey = args[0]
    request['locktime'] = time.time() + int(args[1]) * 60
    request['return_address'] = args[2]

    print "fetching charter url"  # hopefully it didn't check between running main1 and main2
    charter = fetch_charter(CHARTER_URL)

    oracle_pubkeys = []
    oracle_fees = {}
    oracle_bms = []

    for o in charter['nodes']:
        oracle_pubkeys.append(o['pubkey'])
        oracle_fees[o['address']] = o['fee']
        oracle_bms.append(o['bm'])

    oracle_fees[charter['org_address']] = charter['org_fee']

    min_sigs = int(ceil(float(len(oracle_pubkeys)) / 2))

    key_list = [client_pubkey] + oracle_pubkeys

    response = btc.create_multisig_address(min_sigs, key_list)
    msig_addr = response['address']  # we're using this as an identificator
    redeemScript = response['redeemScript']

    request['message_id'] = "%s-%s" % (msig_addr,
                                       str(randrange(1000000000, 9000000000)))
    request['pubkey_list'] = key_list

    request['miners_fee_satoshi'] = MINERS_FEE

    print "fetching transactions incoming to %s ..." % msig_addr

    # for production purposes you might want to fetch the data using bitcoind, but that's expensive
    address_json = liburl_wrapper.safe_read(
        "https://blockchain.info/address/%s?format=json" % msig_addr,
        timeout_time=10)
    try:
        address_history = json.loads(address_json)
    except:
        print "blockchain.info problem"
        print address_json
        return

    prevtxs = []
    sum_satoshi = 0

    for tx in address_history['txs']:
        outputs = []
        if 'out' in tx:
            outputs = outputs + tx['out']
        if 'outputs' in tx:
            outputs = outputs + tx['outputs']

        for vout in tx['out']:
            print vout
            if vout['addr'] == msig_addr:
                prevtx = {
                    'scriptPubKey': vout['script'],
                    'vout': vout['n'],
                    'txid': tx['hash'],
                    'redeemScript': redeemScript,
                }
                sum_satoshi += vout['value']
                prevtxs.append(prevtx)

    if len(prevtxs) == 0:
        print "ERROR: couldn't find transactions sending money to %s" % msig_addr
        return

    request['prevtxs'] = prevtxs
    request['outputs'] = oracle_fees

    request["req_sigs"] = min_sigs
    request['operation'] = 'timelock_create'
    request['sum_satoshi'] = sum_satoshi

    bm = BitmessageClient()
    print "sending: %r" % json.dumps(request)
    print bm.chan_address

    request_content = json.dumps(request)

    print bm.send_message(bm.chan_address, request['operation'],
                          request_content)

    print ""
    print "Gathering oracle responses. It may take BitMessage 30-60 seconds to deliver a message one way."
    print "Although we've seen delays up to half an hour, especially if BitMessage client was just launched."
    print ""

    oracles_confirmed = 0
    while oracle_bms:
        messages = bm.get_unread_messages()
        print "oracles confirmed: {}".format(oracles_confirmed)
        for msg in messages:
            if msg.from_address in oracle_bms:
                try:
                    content = json.loads(msg.message)
                except:
                    print msg.message
                    print 'failed decoding message'
                    continue

                if 'in_reply_to' not in content:
                    continue

                if content['in_reply_to'] == request['message_id']:
                    print "[%r][%r] %r" % (msg.subject, msg.from_address,
                                           msg.message)
                    print ""
                    oracle_bms.remove(msg.from_address)

        if oracle_bms:  #if still awaiting replies from some oracles
            time.sleep(10)
Esempio n. 4
0
class OracleCommunication:
    def __init__(self):
        self.client = BitmessageClient()

        # Do we really need it here?
        self.default_address = self.client.default_address
        logging.info("my BM address: %r" % self.client.default_address)

    def corresponds_to_protocol(self, message):
        try:
            body = json.loads(message.message)
        except ValueError:
            logging.info('message is not a valid json')
            return False
        if not 'operation' in body:
            logging.info('message has no operation')
            return False

        if not body['operation'] in op_handlers:
            logging.info('operation %r not supported' % body['operation'])
            return False

        operation = body['operation']

        if operation in OPERATION_REQUIRED_FIELDS:
            required_fields = OPERATION_REQUIRED_FIELDS[operation]
            for field in required_fields:
                if not field in body:
                    logging.info(
                        'required field {0} for operation {1} missing'.format(
                            field, operation))
                    return False
        else:
            logging.warning(
                'operation %r has no OPERATION_REQUIRED_FIELDS defined' %
                operation)

        logging.info('operation {0}'.format(operation))
        return operation

    def get_new_requests(self):
        messages = self.client.get_unread_messages()
        requests = []
        for msg in messages:
            if msg.direct:
                self.response(msg, 'DirectMessage',
                              'direct message unsupported')
                continue
            operation = self.corresponds_to_protocol(msg)
            if operation:
                requests.append((operation, msg))
            else:
                # If message is not corresponding to protocol, then mark it as read
                # All other messages will me marked later
                self.client.mark_message_as_read(msg)
        return requests

    def mark_request_done(self, request):
        operation, message = request
        self.client.mark_message_as_read(message)

    def response(self, message, subject, response):
        self.response_to_address(message.from_address, subject, response)

    def response_to_address(self, address, subject, response):
        body = {}
        body['version'] = PROTOCOL_VERSION
        body['response'] = response
        body_json = json.dumps(body)
        self.client.send_message(address, subject, body_json)

    def broadcast(self, subject, message):
        self.client.send_message(self.client.chan_address, subject, message)

    def broadcast_identity(self):

        IDENTITY_MESSAGE_RAW = {
            "response": "active",
            "version": PROTOCOL_VERSION
        }

        self.client.send_broadcast('IdentityBroadcast',
                                   json.dumps(IDENTITY_MESSAGE_RAW))
Esempio n. 5
0
class OracleCommunication:

  def __init__(self):
    self.client = BitmessageClient()

    # Do we really need it here?
    self.default_address = self.client.default_address
    logging.info("my BM address: %r" % self.client.default_address)


  def corresponds_to_protocol(self, message):
    try:
      body = json.loads(message.message)
    except ValueError:
      logging.info('message is not a valid json')
      return False
    if not 'operation' in body:
      logging.info('message has no operation')
      return False

    if not body['operation'] in op_handlers:
      logging.info('operation %r not supported' % body['operation'])
      return False

    operation = body['operation']

    if operation in OPERATION_REQUIRED_FIELDS:
      required_fields = OPERATION_REQUIRED_FIELDS[operation]
      for field in required_fields:
        if not field in body:
          logging.info('required field {0} for operation {1} missing'.format(field, operation))
          return False
    else:
      logging.warning('operation %r has no OPERATION_REQUIRED_FIELDS defined' % operation)

    logging.info('operation {0}'.format(operation))
    return operation

  def get_new_requests(self):
    messages = self.client.get_unread_messages()
    requests = []
    for msg in messages:
      if msg.direct:
        self.response(msg, 'DirectMessage', 'direct message unsupported')
        continue
      operation = self.corresponds_to_protocol(msg)
      if operation:
        requests.append((operation, msg))
      else:
        # If message is not corresponding to protocol, then mark it as read
        # All other messages will me marked later
        self.client.mark_message_as_read(msg)
    return requests

  def mark_request_done(self, request):
    operation, message = request
    self.client.mark_message_as_read(message)

  def response(self, message, subject, response):
    self.response_to_address(message.from_address, subject, response)

  def response_to_address(self, address, subject, response):
    body = {}
    body['version'] = PROTOCOL_VERSION
    body['response'] = response
    body_json = json.dumps(body)
    self.client.send_message(
        address,
        subject,
        body_json)


  def broadcast(self, subject, message):
    self.client.send_message(self.client.chan_address, subject, message)

  def broadcast_identity(self):

    IDENTITY_MESSAGE_RAW = {
      "response": "active",
      "version": PROTOCOL_VERSION
    }

    self.client.send_broadcast(
        'IdentityBroadcast',
        json.dumps(IDENTITY_MESSAGE_RAW))