Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee50ef60b9 | ||
|
|
64119f8baa | ||
|
|
1f7cbcfa13 | ||
|
|
c4f1c8b5af | ||
|
|
3618687377 | ||
|
|
498d0064cd | ||
|
|
c9a58a7305 | ||
|
|
a386de5197 | ||
|
|
0a3bf90767 | ||
| 042f3da96e | |||
|
|
282edba6a0 | ||
|
|
09c24b370f | ||
|
|
05f2f09043 |
5
.gitignore
vendored
5
.gitignore
vendored
@ -3,5 +3,6 @@ build/
|
||||
dist/
|
||||
.github/
|
||||
pybtc.egg-info/
|
||||
*.pyc
|
||||
|
||||
pyflo.egg-info/
|
||||
pyflo_lib.egg-info/
|
||||
*.pyc
|
||||
101
README.md
101
README.md
@ -63,3 +63,104 @@ 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);
|
||||
|
||||
```
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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'\x05'
|
||||
MAINNET_SCRIPT_ADDRESS_BYTE_PREFIX = b'\x5e'
|
||||
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,7 +22,8 @@ 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 = '3'
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX = 'e'
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2 = 'f'
|
||||
TESTNET_SCRIPT_ADDRESS_PREFIX = '2'
|
||||
|
||||
MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX = '5'
|
||||
@ -35,6 +36,7 @@ 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,7 +129,8 @@ 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,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2):
|
||||
t = 'P2SH'
|
||||
elif address[0] in (MAINNET_ADDRESS_PREFIX,
|
||||
TESTNET_ADDRESS_PREFIX,
|
||||
@ -155,7 +156,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,
|
||||
if address[0] in (MAINNET_SCRIPT_ADDRESS_PREFIX, MAINNET_SCRIPT_ADDRESS_PREFIX_2,
|
||||
MAINNET_ADDRESS_PREFIX):
|
||||
return "mainnet"
|
||||
elif address[:2] == MAINNET_SEGWIT_ADDRESS_PREFIX:
|
||||
@ -178,7 +179,8 @@ 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,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2):
|
||||
s = [OP_HASH160,
|
||||
b'\x14',
|
||||
address_to_hash(address, hex=False),
|
||||
@ -222,6 +224,7 @@ 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):
|
||||
@ -232,7 +235,8 @@ 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,
|
||||
MAINNET_SCRIPT_ADDRESS_PREFIX_2):
|
||||
return False
|
||||
h = decode_base58(address)
|
||||
if len(h) != 25:
|
||||
@ -275,11 +279,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,6 +22,7 @@ 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):
|
||||
@ -165,9 +166,6 @@ 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.
|
||||
@ -404,6 +402,33 @@ 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
|
||||
@ -613,5 +638,4 @@ 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='pybtc',
|
||||
setup(name='pyflo-lib',
|
||||
version='2.0.9',
|
||||
description='Python Bitcoin library',
|
||||
keywords='bitcoin',
|
||||
url='https://github.com/bitaps-com/pybtc',
|
||||
author='Alexsei Karpov',
|
||||
author_email='admin@bitaps.com',
|
||||
description='Python FLO library',
|
||||
keywords='flo',
|
||||
url='https://github.com/ranchimall/pyflo',
|
||||
author='Ranchi Mall',
|
||||
author_email='ranchimallfze@gmail.com',
|
||||
license='GPL-3.0',
|
||||
packages=find_packages(),
|
||||
install_requires=['secp256k1'],
|
||||
include_package_data=True,
|
||||
package_data={
|
||||
'pybtc': ['bip39_word_list/*.txt', 'test/*.txt'],
|
||||
'pyflo': ['bip39_word_list/*.txt', 'test/*.txt'],
|
||||
},
|
||||
test_suite='tests',
|
||||
zip_safe=False)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user