Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update token uri #23

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7e1e9e8
Example for v3, update cert-schema, issuing v3 w/ old MerkleProof
Jan 15, 2020
e7051ca
Integrated MerkleProof2019 into v3 issuing
Jan 21, 2020
2a3adb4
#164 - Updated MerkleProof2019 to support mocknet & bitcoin regtest
Jan 23, 2020
a40a772
Allowing issuer url/did's for verification method of ld merkle proof
Jan 27, 2020
b1c4647
bump cert-schema to 3.0.0a2
Feb 13, 2020
830ee9d
RI etherscan changes from v2 to v3
Feb 19, 2020
625b1f1
v3-alpha schema updates
Feb 19, 2020
df2a44f
Fix test using proof instead of signature for v3
Feb 20, 2020
c64f477
Bump v3-alpha schema to 3.0.0a3
Feb 20, 2020
24a4f4f
Bump v3-alpha schema to 3.0.0a4
Mar 11, 2020
f85bd55
updated for bloxberg
JamesLawton Jun 30, 2020
7f0d1db
updated pathing for merkle tree
JamesLawton Jul 3, 2020
e35071c
updated with ERC721 bloxberg contracts
JamesLawton Jul 6, 2020
c8dd8d2
updated issuing for bloxberg
JamesLawton Jul 17, 2020
80b2a33
updated API for bloxberg
JamesLawton Jul 23, 2020
dfb6bcc
updated VC schema
JamesLawton Jul 23, 2020
155f614
Merge branch 'blockchain-certificates-v3'
JamesLawton Jul 23, 2020
5cdb14b
updated smart contract merkle proof anchors
JamesLawton Jul 24, 2020
c3074b2
changed anchor structure in merkle tree
JamesLawton Jul 30, 2020
2459d4b
updated bloxberg as blink
JamesLawton Aug 12, 2020
a8b3a72
updated proof mapping and initial IPFS functions
JamesLawton Aug 20, 2020
05ffa02
added certificate validation for v3
andionita Aug 25, 2020
f2d4efe
added ipfs_batch_file in conf
andionita Aug 25, 2020
bba5667
added updating of token uri with ipfs batch file
andionita Aug 25, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .app.py.swp
Binary file not shown.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.tox
*egg-info
venv
pk
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ venv*/
virtual\ usb/
secrets.py
__pycache__

pk
certs_dbdump.csv

data/unsigned_certificates/
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
sudo: false
language: python
python:
- "3.4"
- "3.6"
install: pip install tox-travis
script: tox
12 changes: 12 additions & 0 deletions Dockerfilebloxberg
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7

EXPOSE 80

COPY ./app /app/app
COPY ./cert_issuer /app/cert_issuer
COPY ./sample_data /app/sample_data
COPY ethereum_smart_contract_requirements.txt .
COPY conf.ini .

RUN pip install -r ethereum_smart_contract_requirements.txt

11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ If you are using a local bitcoin node, you can create addresses by command line.

### Create an Ethereum issuing address

Currently Blockcerts just supports issuing to the Ropsten Ethereum testnet, and the Ethereum mainnet. In Ethereum a public/private key pair is the same accross all test/main networks.
Currently Blockcerts just supports issuing to the Bloxberg Ethereum testnet, and the Ethereum mainnet. In Ethereum a public/private key pair is the same accross all test/main networks.

__These steps involve storing secure information on a USB. Do not plug in this USB when your computer's wifi is on.__

Expand Down Expand Up @@ -265,7 +265,10 @@ Edit your conf.ini file (the config file for this application).
```
issuing_address = <issuing-address>

chain=<bitcoin_regtest|bitcoin_testnet|bitcoin_mainnet|ethereum_ropsten|ethereum_mainnet|mockchain>
# issuer URL / DID
verification_method = <verification-method>

chain=<bitcoin_regtest|bitcoin_testnet|bitcoin_mainnet|ethereum_bloxberg|ethereum_mainnet|mockchain>

usb_name = </Volumes/path-to-usb/>
key_file = <file-you-saved-pk-to>
Expand Down Expand Up @@ -298,7 +301,7 @@ python cert-issuer -c conf.ini
- The Blockchain Certificates will be located in data/blockchain_certificates.
- If you ran in the mainnet or testnet mode, you can also see your transaction on a live blockchain explorer.
- For Bitcoin, Blockr.io has explorers for both [testnet](https://tbtc.blockr.io/) and [mainnet](https://blockr.io/).
- For Ethereum, Etherscan has explorers for [ropsten](https://ropsten.etherscan.io/) and [mainnet](https://etherscan.io/)
- For Ethereum, Etherscan has explorers for [bloxberg](https://bloxberg.etherscan.io/) and [mainnet](https://etherscan.io/)
- The transaction id is located in the Blockchain Certificate under `signature.anchors[0].sourceId`


Expand Down Expand Up @@ -397,7 +400,7 @@ For an Ethereum transaction, you'll need to use a different explorer, which migh
output. To view a transaction in a web browser, you might try something like this:

- Ethereum Mainnet: https://etherscan.io/tx/0xf537d81667c8011e34e1f450e18fd1c5a8a10c770cd0acdc91a79746696f36a3
- Ethereum Ropsten (testnet): https://ropsten.etherscan.io/tx/0xf537d81667c8011e34e1f450e18fd1c5a8a10c770cd0acdc91a79746696f36a3
- Ethereum Bloxberg (testnet): https://bloxberg.etherscan.io/tx/0xf537d81667c8011e34e1f450e18fd1c5a8a10c770cd0acdc91a79746696f36a3

## Mac scrypt problems

Expand Down
6 changes: 4 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from subprocess import call

import cert_issuer.config
from cert_issuer.blockchain_handlers import bitcoin
from cert_issuer.blockchain_handlers import ethereum_sc
import cert_issuer.issue_certificates

app = Flask(__name__)
Expand All @@ -20,7 +20,9 @@ def get_config():
def issue():
config = get_config()
certificate_batch_handler, transaction_handler, connector = \
bitcoin.instantiate_blockchain_handlers(config, False)
ethereum_sc.instantiate_blockchain_handlers(config)
#Removed File mode from ethereum_sc
#bitcoin.instantiate_blockchain_handlers(config, False)
certificate_batch_handler.set_certificates_in_batch(request.json)
cert_issuer.issue_certificates.issue(config, certificate_batch_handler, transaction_handler)
return json.dumps(certificate_batch_handler.proof)
Expand Down
48 changes: 48 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from typing import List, Optional
from functools import lru_cache
from fastapi import Depends, FastAPI
from cert_tools import instantiate_v3_alpha_certificate_batch, create_v3_alpha_certificate_template
from pydantic import BaseModel
import configargparse
import os

app = FastAPI()


@app.get("/")
def read_root():
return {"Hello": "World"}

class Batch(BaseModel):
publicKey: str
recipient_name: Optional[str]
email: Optional[str]
SHA256: List[str]

class Config:
schema_extra = {
"example": {
"publicKey": "0x69575606E8b8F0cAaA5A3BD1fc5D032024Bb85AF",
"recipient_name": "Albert Einstein",
"email": "[email protected]",
"SHA256": ["0x0e4ded5319861c8daac00d425c53a16bd180a7d01a340a0e00f7dede40d2c9f6", "0xfda3124d5319861c8daac00d425c53a16bd180a7d01a340a0e00f7dede40d2c9f6"],
}
}


@app.post("/createUnsignedCertificateBatch")
def createUnsignedCertificate(batch: Batch):
#create_v3_alpha_certificate_template(recipient_name, email)
conf = create_v3_alpha_certificate_template.get_config()
create_v3_alpha_certificate_template.write_certificate_template(conf, batch.recipient_name, batch.email)
conf_instantiate = instantiate_v3_alpha_certificate_batch.get_config()
instantiate_v3_alpha_certificate_batch.instantiate_batch(conf_instantiate, batch.publicKey, batch.recipient_name, batch.email, batch.SHA256)

return {"Unsigned Certificate Created!"}

@app.post("/createCertificateBatch")
def createCertificateBatch(batch: Batch):
conf = instantiate_v3_alpha_certificate_batch.get_config()
instantiate_v3_alpha_certificate_batch.instantiate_batch(conf, batch.publicKey, batch.recipient_name, batch.email, batch.SHA256)

return {"Batch Created!"}
2 changes: 1 addition & 1 deletion cert_issuer/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.0.20'
__version__ = '3.0.0a3'
1 change: 1 addition & 0 deletions cert_issuer/blockchain_handlers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = '2.0.20'
12 changes: 7 additions & 5 deletions cert_issuer/blockchain_handlers/bitcoin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from cert_issuer.blockchain_handlers.bitcoin.connectors import BitcoinServiceProviderConnector, MockServiceProviderConnector
from cert_issuer.blockchain_handlers.bitcoin.signer import BitcoinSigner
from cert_issuer.blockchain_handlers.bitcoin.transaction_handlers import BitcoinTransactionHandler
from cert_issuer.certificate_handlers import CertificateBatchHandler, CertificateV2Handler, CertificateBatchWebHandler, CertificateWebV2Handler
from cert_issuer.certificate_handlers import CertificateBatchHandler, CertificateV3Handler, CertificateBatchWebHandler, CertificateWebV3Handler
from cert_issuer.merkle_tree_generator import MerkleTreeGenerator
from cert_issuer.models import MockTransactionHandler
from cert_issuer.signer import FileSecretManager
Expand Down Expand Up @@ -50,12 +50,14 @@ def instantiate_blockchain_handlers(app_config, file_mode=True):

if file_mode:
certificate_batch_handler = CertificateBatchHandler(secret_manager=secret_manager,
certificate_handler=CertificateV2Handler(),
merkle_tree=MerkleTreeGenerator())
certificate_handler=CertificateV3Handler(),
merkle_tree=MerkleTreeGenerator(),
config=app_config)
else:
certificate_batch_handler = CertificateBatchWebHandler(secret_manager=secret_manager,
certificate_handler=CertificateWebV2Handler(),
merkle_tree=MerkleTreeGenerator())
certificate_handler=CertificateWebV3Handler(),
merkle_tree=MerkleTreeGenerator(),
config=app_config)
if chain == Chain.mockchain:
transaction_handler = MockTransactionHandler()
connector = MockServiceProviderConnector()
Expand Down
9 changes: 5 additions & 4 deletions cert_issuer/blockchain_handlers/ethereum/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from cert_core import BlockchainType
from cert_core import Chain, UnknownChainError

from cert_issuer.certificate_handlers import CertificateBatchHandler, CertificateV2Handler
from cert_issuer.certificate_handlers import CertificateBatchHandler, CertificateV3Handler
from cert_issuer.blockchain_handlers.ethereum.connectors import EthereumServiceProviderConnector
from cert_issuer.blockchain_handlers.ethereum.signer import EthereumSigner
from cert_issuer.blockchain_handlers.ethereum.transaction_handlers import EthereumTransactionHandler
Expand Down Expand Up @@ -54,12 +54,13 @@ def instantiate_blockchain_handlers(app_config):
chain = app_config.chain
secret_manager = initialize_signer(app_config)
certificate_batch_handler = CertificateBatchHandler(secret_manager=secret_manager,
certificate_handler=CertificateV2Handler(),
merkle_tree=MerkleTreeGenerator())
certificate_handler=CertificateV3Handler(),
merkle_tree=MerkleTreeGenerator(),
config=app_config)
if chain == Chain.mockchain:
transaction_handler = MockTransactionHandler()
# ethereum chains
elif chain == Chain.ethereum_mainnet or chain == Chain.ethereum_ropsten:
elif chain == Chain.ethereum_mainnet or chain == Chain.ethereum_bloxberg:
cost_constants = EthereumTransactionCostConstants(app_config.gas_price, app_config.gas_limit)
connector = EthereumServiceProviderConnector(chain, app_config.api_token)
transaction_handler = EthereumTransactionHandler(connector, cost_constants, secret_manager,
Expand Down
19 changes: 12 additions & 7 deletions cert_issuer/blockchain_handlers/ethereum/connectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,14 @@ def broadcast_tx(self, tx, api_token):

broadcast_url = self.base_url + '?module=proxy&action=eth_sendRawTransaction'
if api_token:
'&apikey=%s' % api_token
broadcast_url += '&apikey=%s' % api_token
response = requests.post(broadcast_url, data={'hex': tx_hex})
if 'error' in response.json():
logging.error("Etherscan returned an error: %s", response.json()['error'])
raise BroadcastError(response.json()['error'])
if int(response.status_code) == 200:
if response.json().get('message', None) == 'NOTOK':
raise BroadcastError(response.json().get('result', None))
tx_id = response.json().get('result', None)
logging.info("Transaction ID obtained from broadcast through Etherscan: %s", tx_id)
return tx_id
Expand All @@ -116,9 +118,11 @@ def get_balance(self, address, api_token):
broadcast_url += '&address=%s' % address
broadcast_url += '&tag=latest'
if api_token:
'&apikey=%s' % api_token
broadcast_url += '&apikey=%s' % api_token
response = requests.get(broadcast_url)
if int(response.status_code) == 200:
if response.json().get('message', None) == 'NOTOK':
raise BroadcastError(response.json().get('result', None))
balance = int(response.json().get('result', None))
logging.info('Balance check succeeded: %s', response.json())
return balance
Expand All @@ -133,10 +137,11 @@ def get_address_nonce(self, address, api_token):
broadcast_url += '&address=%s' % address
broadcast_url += '&tag=latest'
if api_token:
'&apikey=%s' % api_token
broadcast_url += '&apikey=%s' % api_token
response = requests.get(broadcast_url, )
if int(response.status_code) == 200:
# the int(res, 0) transforms the hex nonce to int
if response.json().get('message', None) == 'NOTOK':
raise BroadcastError(response.json().get('result', None))
nonce = int(response.json().get('result', None), 0)
logging.info('Nonce check went correct: %s', response.json())
return nonce
Expand Down Expand Up @@ -219,11 +224,11 @@ def get_address_nonce(self, address, api_token):
eth_provider_list.append(MyEtherWalletBroadcaster('https://api.myetherwallet.com/eth'))
connectors[Chain.ethereum_mainnet] = eth_provider_list

# Configure Ethereum Ropsten testnet connectors
# Configure Ethereum Bloxberg testnet connectors
rop_provider_list = []
rop_provider_list.append(EtherscanBroadcaster('https://ropsten.etherscan.io/api'))
rop_provider_list.append(EtherscanBroadcaster('https://blockexplorer.bloxberg.org/api'))
rop_provider_list.append(MyEtherWalletBroadcaster('https://api.myetherwallet.com/rop'))
connectors[Chain.ethereum_ropsten] = rop_provider_list
connectors[Chain.ethereum_bloxberg] = rop_provider_list


def get_providers_for_chain(chain, local_node=False):
Expand Down
2 changes: 1 addition & 1 deletion cert_issuer/blockchain_handlers/ethereum/signer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def __init__(self, ethereum_chain):
# Netcode ensures replay protection (see EIP155)
if ethereum_chain.external_display_value == 'ethereumMainnet':
self.netcode = 1
elif ethereum_chain.external_display_value == 'ethereumRopsten':
elif ethereum_chain.external_display_value == 'ethereumBloxberg':
self.netcode = 3
else:
self.netcode = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def ensure_balance(self):
logging.error(error_message)
raise InsufficientFundsError(error_message)

def issue_transaction(self, blockchain_bytes, app_config):
def issue_transaction(self, recipient_address, token_uri, blockchain_bytes, app_config):
eth_data_field = b2h(blockchain_bytes)
prepared_tx = self.create_transaction(blockchain_bytes)
signed_tx = self.sign_transaction(prepared_tx)
Expand Down
Binary file not shown.
9 changes: 5 additions & 4 deletions cert_issuer/blockchain_handlers/ethereum_sc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from cert_core import BlockchainType
from cert_core import Chain, UnknownChainError

from cert_issuer.certificate_handlers import CertificateBatchHandler, CertificateV2Handler
from cert_issuer.certificate_handlers import CertificateBatchHandler, CertificateV3Handler
from cert_issuer.blockchain_handlers.ethereum_sc.connectors import EthereumSCServiceProviderConnector
from cert_issuer.blockchain_handlers.ethereum_sc.ens import ENSConnector
from cert_issuer.blockchain_handlers.ethereum_sc.signer import EthereumSCSigner
Expand Down Expand Up @@ -82,12 +82,13 @@ def instantiate_blockchain_handlers(app_config):
chain = app_config.chain
secret_manager = initialize_signer(app_config)
certificate_batch_handler = CertificateBatchHandler(secret_manager=secret_manager,
certificate_handler=CertificateV2Handler(),
merkle_tree=MerkleTreeGenerator())
certificate_handler=CertificateV3Handler(),
merkle_tree=MerkleTreeGenerator(),
config=app_config)
if chain == Chain.mockchain:
transaction_handler = MockTransactionHandler()
# ethereum chains
elif chain == Chain.ethereum_mainnet or chain == Chain.ethereum_ropsten:
elif chain == Chain.ethereum_mainnet or chain == Chain.ethereum_bloxberg:
cost_constants = EthereumTransactionCostConstants(app_config.gas_price, app_config.gas_limit)
connector = instantiate_connector(app_config, cost_constants)
transaction_handler = EthereumSCTransactionHandler(connector, cost_constants, secret_manager,
Expand Down
20 changes: 16 additions & 4 deletions cert_issuer/blockchain_handlers/ethereum_sc/connectors.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
import os
import logging
from errors import UnableToSignTxError
from cert_issuer.errors import UnableToSignTxError

from cert_issuer.models import ServiceProviderConnector
from web3 import Web3, HTTPProvider
Expand All @@ -15,6 +15,7 @@ def get_abi(contract):

directory = os.path.dirname(os.path.abspath(__file__))
path = os.path.join(directory, f"data/{contract}_abi.json")
print(path)

with open(path, "r") as f:
raw = f.read()
Expand Down Expand Up @@ -49,21 +50,26 @@ def get_balance(self, address):

def create_transaction(self, method, *argv):
gas_limit = self.cost_constants.get_gas_limit()
estimated_gas = self._contract_obj.functions[method](*argv).estimateGas() * 2
estimated_gas = self._contract_obj.functions[method](*argv).estimateGas() * 5
if estimated_gas > gas_limit:
logging.warning("Estimated gas of %s more than gas limit of %s, transaction might fail. Please verify on etherescan.com.", estimated_gas, gas_limit)
logging.warning("Estimated gas of %s more than gas limit of %s, transaction might fail. Please verify on blockexplorer.bloxberg.org.", estimated_gas, gas_limit)
estimated_gas = gas_limit

gas_price = self._w3.eth.gasPrice
gas_price_limit = self.cost_constants.get_gas_price()

print("gas price: " + str(gas_price))
print("gas_price_limit: " + str(gas_price_limit))
print("estimated_gas: " + str(estimated_gas))

if gas_price > gas_price_limit:
logging.warning("Gas price provided by network of %s higher than gas price of %s set in config, transaction might fail. Please verify on etherescan.com.", gas_price, gas_price_limit)
gas_price = gas_price_limit

tx_options = {
'nonce': self._w3.eth.getTransactionCount(self._w3.eth.defaultAccount),
'gas': estimated_gas,
'gas': 700000,
#'gas': estimated_gas,
'gasPrice': gas_price
}

Expand Down Expand Up @@ -101,3 +107,9 @@ def _sign_transaction(self, prepared_tx):

def call(self, method, *argv):
return self._contract_obj.functions[method](*argv).call()

def get_event_args(self, tx_hash, event):
tx_receipt = self._w3.eth.getTransactionReceipt(tx_hash)
logs = self._contract_obj.events[event]().processReceipt(tx_receipt)
return logs[0]['args']

4 changes: 2 additions & 2 deletions cert_issuer/blockchain_handlers/ethereum_sc/ens.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ def __init__(self, app_config):
self._w3 = Web3(HTTPProvider())

def get_registry_address(self):
if self.app_config.chain == Chain.ethereum_ropsten:
addr = self.app_config.ens_registry_ropsten
if self.app_config.chain == Chain.ethereum_bloxberg:
addr = self.app_config.ens_registry_bloxberg
else:
addr = self.app_config.ens_registry_mainnet

Expand Down
6 changes: 3 additions & 3 deletions cert_issuer/blockchain_handlers/ethereum_sc/signer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ def __init__(self, ethereum_chain):
self.ethereum_chain = ethereum_chain
# Netcode ensures replay protection (see EIP155)
if ethereum_chain.external_display_value == 'ethereumMainnet':
self.netcode = 1
elif ethereum_chain.external_display_value == 'ethereumRopsten':
self.netcode = 3
self.netcode = 8995
elif ethereum_chain.external_display_value == 'ethereumBloxberg':
self.netcode = 8995
else:
self.netcode = None

Expand Down
Loading