Compare commits

..

No commits in common. "master" and "pr/2" have entirely different histories.
master ... pr/2

23 changed files with 24 additions and 156 deletions

5
.gitignore vendored
View File

@ -3,6 +3,5 @@ build/
dist/
.github/
pybtc.egg-info/
pyflo.egg-info/
pyflo_lib.egg-info/
*.pyc
*.pyc

101
README.md
View File

@ -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);
```

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.

View File

@ -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,

View File

@ -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]

View File

@ -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

View File

@ -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)

View File

@ -1,9 +1,9 @@
import unittest
import pyflo.test
import pybtc.test
testLoad = unittest.TestLoader()
suites = testLoad.loadTestsFromModule(pyflo.test)
suites = testLoad.loadTestsFromModule(pybtc.test)
runner = unittest.TextTestRunner(verbosity=1)
runner.run(suites)