Implemented /txinfo/ethereum_blockchain

This is an authentiated endpoint which currently returns decoded ABI
information from input bytecode in an Ethereum transaction.

In the future, we should add all transaction display enrichment code to
this endpoint (for Ethereum blockchain transactions).
pull/18/head
Neeraj Kashyap 2021-07-28 12:43:02 -07:00
rodzic c02fabe967
commit b9aebfddf7
5 zmienionych plików z 166 dodań i 0 usunięć

Wyświetl plik

@ -9,6 +9,7 @@ from fastapi.middleware.cors import CORSMiddleware
from . import data
from .routes.subscriptions import app as subscriptions_api
from .routes.users import app as users_api
from .routes.txinfo import app as txinfo_api
from .settings import ORIGINS
from .version import MOONSTREAM_VERSION
@ -38,3 +39,4 @@ async def version_handler() -> data.VersionResponse:
app.mount("/subscriptions", subscriptions_api)
app.mount("/users", users_api)
app.mount("/txinfo", txinfo_api)

Wyświetl plik

@ -88,3 +88,24 @@ class EVMEventSignature(BaseModel):
class ContractABI(BaseModel):
functions: List[EVMFunctionSignature]
events: List[EVMEventSignature]
class EthereumTransaction(BaseModel):
gas: int
gasPrice: int
value: int
from_address: str = Field(alias="from")
to_address: Optional[str] = Field(default=None, alias="to")
hash: Optional[str] = None
input: Optional[str] = None
class TxinfoEthereumBlockchainRequest(BaseModel):
tx: EthereumTransaction
class TxinfoEthereumBlockchainResponse(BaseModel):
tx: EthereumTransaction
abi: Optional[ContractABI] = None
errors: List[str] = Field(default_factory=list)

Wyświetl plik

@ -0,0 +1,80 @@
"""
Moonstream's /txinfo endpoints.
These endpoints enrich raw blockchain transactions (as well as pending transactions, hypothetical
transactions, etc.) with side information and return objects that are better suited for displaying to
end users.
"""
import logging
from typing import Any, Dict
from fastapi import (
FastAPI,
Depends,
HTTPException,
Request,
)
from fastapi.middleware.cors import CORSMiddleware
from moonstreamdb.db import yield_db_session
from sqlalchemy.orm import Session
from ..abi_decoder import decode_abi
from ..data import TxinfoEthereumBlockchainRequest, TxinfoEthereumBlockchainResponse
from ..middleware import BroodAuthMiddleware
from ..settings import (
MOONSTREAM_APPLICATION_ID,
DOCS_TARGET_PATH,
ORIGINS,
DOCS_PATHS,
bugout_client as bc,
)
from ..version import MOONSTREAM_VERSION
logger = logging.getLogger(__name__)
tags_metadata = [
{"name": "users", "description": "Operations with users."},
{"name": "tokens", "description": "Operations with user tokens."},
]
app = FastAPI(
title=f"Moonstream users API.",
description="User, token and password handlers.",
version=MOONSTREAM_VERSION,
openapi_tags=tags_metadata,
openapi_url="/openapi.json",
docs_url=None,
redoc_url=f"/{DOCS_TARGET_PATH}",
)
app.add_middleware(
CORSMiddleware,
allow_origins=ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
whitelist_paths: Dict[str, str] = {}
whitelist_paths.update(DOCS_PATHS)
app.add_middleware(BroodAuthMiddleware, whitelist=whitelist_paths)
@app.post(
"/ethereum_blockchain",
tags=["txinfo"],
response_model=TxinfoEthereumBlockchainResponse,
)
async def txinfo_ethereum_blockchain_handler(
txinfo_request: TxinfoEthereumBlockchainRequest,
db_session: Session = Depends(yield_db_session),
) -> TxinfoEthereumBlockchainResponse:
response = TxinfoEthereumBlockchainResponse(tx=txinfo_request.tx)
if txinfo_request.tx.input is not None:
try:
response.abi = decode_abi(txinfo_request.tx.input, db_session)
except Exception as err:
logger.error(r"Could not decode ABI:")
logger.error(err)
response.errors.append("Could not decode ABI from the given input")
return response

Wyświetl plik

@ -0,0 +1,52 @@
#!/usr/bin/env bash
TIMESTAMP="$(date +%s)"
SCRIPT_DIR=$(realpath $(dirname $0))
API_URL="${MOONSTREAM_DEV_API_URL:-http://localhost:7481}"
MOONSTREAM_USERNAME="devuser_$TIMESTAMP"
MOONSTREAM_PASSWORD="peppercat"
MOONSTREAM_EMAIL="devuser_$TIMESTAMP@example.com"
OUTPUT_DIR=$(mktemp -d)
echo "Writing responses to directory: $OUTPUT_DIR"
# Create a new user
curl -X POST \
-H "Content-Type: multipart/form-data" \
"$API_URL/users/" \
-F "username=$MOONSTREAM_USERNAME" \
-F "password=$MOONSTREAM_PASSWORD" \
-F "email=$MOONSTREAM_EMAIL" \
-o $OUTPUT_DIR/user.json
# Create a token for this user
curl -X POST \
-H "Content-Type: multipart/form-data" \
"$API_URL/users/token" \
-F "username=$MOONSTREAM_USERNAME" \
-F "password=$MOONSTREAM_PASSWORD" \
-o $OUTPUT_DIR/token.json
API_TOKEN=$(jq -r '.id' $OUTPUT_DIR/token.json)
set -e
ETHEREUM_TXINFO_REQUEST_BODY_JSON=$(jq -r . $SCRIPT_DIR/txinfo_ethereum_blockchain_request.json)
curl -f -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_TOKEN" \
"$API_URL/txinfo/ethereum_blockchain" \
-d "$ETHEREUM_TXINFO_REQUEST_BODY_JSON" \
-o $OUTPUT_DIR/txinfo_response.json
echo "Response:"
jq . $OUTPUT_DIR/txinfo_response.json
if [ "$DEBUG" != true ]
then
echo "Deleting output directory: $OUTPUT_DIR"
echo "Please set DEBUG=true if you would prefer to retain this directory in the future"
rm -r $OUTPUT_DIR
fi

Wyświetl plik

@ -0,0 +1,11 @@
{
"tx": {
"to": null,
"from": "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
"gas": 2265656,
"gasPrice": 1000000000,
"hash": "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
"value": 0,
"input": "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca"
}
}