Compare commits
No commits in common. "master" and "pr/2" have entirely different histories.
5
.gitignore
vendored
5
.gitignore
vendored
@ -3,6 +3,5 @@ build/
|
||||
dist/
|
||||
.github/
|
||||
pybtc.egg-info/
|
||||
pyflo.egg-info/
|
||||
pyflo_lib.egg-info/
|
||||
*.pyc
|
||||
*.pyc
|
||||
|
||||
|
||||
101
README.md
101
README.md
@ -63,104 +63,3 @@ True
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
The **sign_message_standard_ops** function verifies with [RanchiMall standard operations](https://github.com/ranchimall/Standard_Operations).
|
||||
Things to note:
|
||||
The function now takes 2 parameters -
|
||||
|
||||
1. Message in string ( not hex-encoded string)
|
||||
2. Private key in wif (not bytes etc.)
|
||||
The hex parameter has been removed as we are always returning hex in standard ops
|
||||
|
||||
New libraries used - hashlib
|
||||
The elliptical curve folder, holds the code taken from starkbank ecdsa (MIT License)
|
||||
no other additional dependencies
|
||||
|
||||
The signature generated with **sign_message_standard_ops** cannot be verified using purely Pyflo. Users can use the following API to verify signatures
|
||||
|
||||
** Python **
|
||||
```
|
||||
import requests
|
||||
|
||||
url = 'https://flo-sign-validator.duckdns.org'
|
||||
myobj = {'floID': floID,
|
||||
'pubKey': pubKey,
|
||||
'message': message,
|
||||
'sign': sign}
|
||||
|
||||
x = requests.post(url, json = myobj)
|
||||
print(x.text)
|
||||
|
||||
```
|
||||
|
||||
** JavaScript **
|
||||
```
|
||||
fetch("https://flo-sign-validator.duckdns.org", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
floID: floID,
|
||||
pubKey: pubKey,
|
||||
message: message,
|
||||
sign: sign
|
||||
}),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8",
|
||||
},
|
||||
})
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
console.log(data);
|
||||
})
|
||||
.catch((error) => console.error("Error:", error));
|
||||
|
||||
```
|
||||
|
||||
** PHP **
|
||||
```
|
||||
function callAPI($method, $url, $data){
|
||||
$curl = curl_init();
|
||||
switch ($method){
|
||||
case "POST":
|
||||
curl_setopt($curl, CURLOPT_POST, 1);
|
||||
if ($data)
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
break;
|
||||
case "PUT":
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||
if ($data)
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
break;
|
||||
default:
|
||||
if ($data)
|
||||
$url = sprintf("%s?%s", $url, http_build_query($data));
|
||||
}
|
||||
// OPTIONS:
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
||||
'APIKEY: 111111111111111111111',
|
||||
'Content-Type: application/json',
|
||||
));
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
// EXECUTE:
|
||||
$result = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
return $result;
|
||||
}
|
||||
|
||||
$floID = $_POST['floID'];
|
||||
$pubKey = $_POST['floPubKey'];
|
||||
$message = $_POST['message'];
|
||||
$signDataWithFlo = $_POST['signDataWithFlo'];
|
||||
|
||||
|
||||
$data_array = array( "floID" => $floID, "pubKey" => $pubKey, "message" => $message, "sign" => $signDataWithFlo );
|
||||
$make_call = callAPI('POST', 'https://flo-sign-validator.duckdns.org', json_encode($data_array));
|
||||
$response = json_decode($make_call, true);
|
||||
|
||||
print_r($response);
|
||||
|
||||
```
|
||||
|
||||
|
||||
BIN
pyflo/__pycache__/__init__.cpython-36.pyc
Normal file
BIN
pyflo/__pycache__/__init__.cpython-36.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
pyflo/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/address.cpython-36.pyc
Normal file
BIN
pyflo/__pycache__/address.cpython-36.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/address.cpython-38.pyc
Normal file
BIN
pyflo/__pycache__/address.cpython-38.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/block.cpython-36.pyc
Normal file
BIN
pyflo/__pycache__/block.cpython-36.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/block.cpython-38.pyc
Normal file
BIN
pyflo/__pycache__/block.cpython-38.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/consensus.cpython-36.pyc
Normal file
BIN
pyflo/__pycache__/consensus.cpython-36.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/consensus.cpython-38.pyc
Normal file
BIN
pyflo/__pycache__/consensus.cpython-38.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/constants.cpython-36.pyc
Normal file
BIN
pyflo/__pycache__/constants.cpython-36.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/constants.cpython-38.pyc
Normal file
BIN
pyflo/__pycache__/constants.cpython-38.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/opcodes.cpython-36.pyc
Normal file
BIN
pyflo/__pycache__/opcodes.cpython-36.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/opcodes.cpython-38.pyc
Normal file
BIN
pyflo/__pycache__/opcodes.cpython-38.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/transaction.cpython-36.pyc
Normal file
BIN
pyflo/__pycache__/transaction.cpython-36.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/transaction.cpython-38.pyc
Normal file
BIN
pyflo/__pycache__/transaction.cpython-38.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/wallet.cpython-36.pyc
Normal file
BIN
pyflo/__pycache__/wallet.cpython-36.pyc
Normal file
Binary file not shown.
BIN
pyflo/__pycache__/wallet.cpython-38.pyc
Normal file
BIN
pyflo/__pycache__/wallet.cpython-38.pyc
Normal file
Binary file not shown.
@ -14,7 +14,7 @@ ECDSA_SEC256K1_ORDER = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8
|
||||
|
||||
MAINNET_ADDRESS_BYTE_PREFIX = b'\x23'
|
||||
TESTNET_ADDRESS_BYTE_PREFIX = b'\x73'
|
||||
MAINNET_SCRIPT_ADDRESS_BYTE_PREFIX = b'\x5e'
|
||||
MAINNET_SCRIPT_ADDRESS_BYTE_PREFIX = b'\x05'
|
||||
TESTNET_SCRIPT_ADDRESS_BYTE_PREFIX = b'\xc4'
|
||||
MAINNET_SEGWIT_ADDRESS_BYTE_PREFIX = b'\x03\x03\x00\x02\x03'
|
||||
TESTNET_SEGWIT_ADDRESS_BYTE_PREFIX = b'\x03\x03\x00\x14\x02'
|
||||
@ -22,8 +22,7 @@ TESTNET_SEGWIT_ADDRESS_BYTE_PREFIX = b'\x03\x03\x00\x14\x02'
|
||||
MAINNET_ADDRESS_PREFIX = 'F'
|
||||
TESTNET_ADDRESS_PREFIX = 'o'
|
||||
TESTNET_ADDRESS_PREFIX_2 = 'o'
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX = 'e'
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2 = 'f'
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX = '3'
|
||||
TESTNET_SCRIPT_ADDRESS_PREFIX = '2'
|
||||
|
||||
MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX = '5'
|
||||
@ -36,7 +35,6 @@ ADDRESS_PREFIX_LIST = (MAINNET_ADDRESS_PREFIX,
|
||||
TESTNET_ADDRESS_PREFIX,
|
||||
TESTNET_ADDRESS_PREFIX_2,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2,
|
||||
TESTNET_SCRIPT_ADDRESS_PREFIX)
|
||||
|
||||
PRIVATE_KEY_PREFIX_LIST = (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX,
|
||||
|
||||
@ -129,8 +129,7 @@ def address_type(address, num=False):
|
||||
:return: address type in string or numeric format.
|
||||
"""
|
||||
if address[0] in (TESTNET_SCRIPT_ADDRESS_PREFIX,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2):
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX):
|
||||
t = 'P2SH'
|
||||
elif address[0] in (MAINNET_ADDRESS_PREFIX,
|
||||
TESTNET_ADDRESS_PREFIX,
|
||||
@ -156,7 +155,7 @@ def address_net_type(address):
|
||||
:param address: address in base58 or bech32 format.
|
||||
:return: address network type in string format or None.
|
||||
"""
|
||||
if address[0] in (MAINNET_SCRIPT_ADDRESS_PREFIX, MAINNET_SCRIPT_ADDRESS_PREFIX_2,
|
||||
if address[0] in (MAINNET_SCRIPT_ADDRESS_PREFIX,
|
||||
MAINNET_ADDRESS_PREFIX):
|
||||
return "mainnet"
|
||||
elif address[:2] == MAINNET_SEGWIT_ADDRESS_PREFIX:
|
||||
@ -179,8 +178,7 @@ def address_to_script(address, hex=False):
|
||||
:return: public key script in HEX or bytes string.
|
||||
"""
|
||||
if address[0] in (TESTNET_SCRIPT_ADDRESS_PREFIX,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2):
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX):
|
||||
s = [OP_HASH160,
|
||||
b'\x14',
|
||||
address_to_hash(address, hex=False),
|
||||
@ -224,7 +222,6 @@ def is_address_valid(address, testnet=False):
|
||||
return False
|
||||
if address[0] in (MAINNET_ADDRESS_PREFIX,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2,
|
||||
TESTNET_ADDRESS_PREFIX,
|
||||
TESTNET_ADDRESS_PREFIX_2,
|
||||
TESTNET_SCRIPT_ADDRESS_PREFIX):
|
||||
@ -235,8 +232,7 @@ def is_address_valid(address, testnet=False):
|
||||
return False
|
||||
else:
|
||||
if address[0] not in (MAINNET_ADDRESS_PREFIX,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2):
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX):
|
||||
return False
|
||||
h = decode_base58(address)
|
||||
if len(h) != 25:
|
||||
@ -279,11 +275,11 @@ def is_address_valid(address, testnet=False):
|
||||
if checksum != checksum2:
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def get_witness_version(address):
|
||||
address = address.split("1")[1]
|
||||
h = rebase_32_to_5(address)
|
||||
return h[0]
|
||||
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@ from pyflo.functions.tools import bytes_from_hex, int_to_bytes, get_stream
|
||||
from pyflo.functions.hash import hash160, sha256
|
||||
from pyflo.functions.address import hash_to_address
|
||||
from pyflo.functions.key import is_wif_valid, wif_to_private_key
|
||||
import requests, json
|
||||
|
||||
|
||||
def public_key_to_pubkey_script(key, hex=True):
|
||||
@ -166,6 +165,9 @@ def script_to_address(script, testnet=False):
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def decode_script(script, asm=False):
|
||||
"""
|
||||
Decode script to ASM format or to human readable OPCODES string.
|
||||
@ -402,33 +404,6 @@ def verify_signature(sig, pub_key, msg):
|
||||
result = secp256k1_ecdsa_verify(ECDSA_CONTEXT_VERIFY, raw_sig, msg, raw_pubkey)
|
||||
return True if result else False
|
||||
|
||||
|
||||
def verify_signature_standard_ops(sig, pub_key, msg, floID):
|
||||
"""
|
||||
Verify signature for message and given public key
|
||||
|
||||
:param sig: signature in bytes or HEX encoded string.
|
||||
:param pub_key: public key in bytes or HEX encoded string.
|
||||
:param msg: message in bytes, string or HEX encoded string.
|
||||
:flo_id: FLO ID in HEX encoded string.
|
||||
:return: boolean.
|
||||
"""
|
||||
url = 'https://flo-sign-validator.duckdns.org'
|
||||
post_data = {
|
||||
'floID': floID,
|
||||
'pubKey': pub_key,
|
||||
'message': msg,
|
||||
'sign': sig
|
||||
}
|
||||
signature_verification = requests.post(url, json = post_data)
|
||||
signature_verification = json.loads(signature_verification.text)
|
||||
if signature_verification['success']:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def to_base(n, base):
|
||||
if base == 10:
|
||||
return n
|
||||
@ -638,4 +613,5 @@ def is_valid_signature_encoding(sig):
|
||||
# interpreted as a negative number.
|
||||
if (len_s > 1) and (sig[len_r + 6] == 0x00) and (not sig[len_r + 7] & 0x80):
|
||||
return False
|
||||
return True
|
||||
return True
|
||||
|
||||
|
||||
14
setup.py
14
setup.py
@ -4,19 +4,19 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
|
||||
setup(name='pyflo-lib',
|
||||
setup(name='pybtc',
|
||||
version='2.0.9',
|
||||
description='Python FLO library',
|
||||
keywords='flo',
|
||||
url='https://github.com/ranchimall/pyflo',
|
||||
author='Ranchi Mall',
|
||||
author_email='ranchimallfze@gmail.com',
|
||||
description='Python Bitcoin library',
|
||||
keywords='bitcoin',
|
||||
url='https://github.com/bitaps-com/pybtc',
|
||||
author='Alexsei Karpov',
|
||||
author_email='admin@bitaps.com',
|
||||
license='GPL-3.0',
|
||||
packages=find_packages(),
|
||||
install_requires=['secp256k1'],
|
||||
include_package_data=True,
|
||||
package_data={
|
||||
'pyflo': ['bip39_word_list/*.txt', 'test/*.txt'],
|
||||
'pybtc': ['bip39_word_list/*.txt', 'test/*.txt'],
|
||||
},
|
||||
test_suite='tests',
|
||||
zip_safe=False)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user