Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
nucleo
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Santiago
nucleo
Commits
57f3f69d
Commit
57f3f69d
authored
4 years ago
by
Robert Martin-Legene
Browse files
Options
Downloads
Patches
Plain Diff
Mejorando libbfa.py
parent
a386bbb6
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
bin/libbfa/README.md
+7
-0
7 additions, 0 deletions
bin/libbfa/README.md
bin/libbfa/__init__.py
+96
-36
96 additions, 36 deletions
bin/libbfa/__init__.py
with
103 additions
and
36 deletions
bin/libbfa/README.md
+
7
−
0
View file @
57f3f69d
...
...
@@ -126,3 +126,10 @@ print(majorcontr.functions.councilLength.call())
# Fix
print
(
majorcontr
.
functions
.
councilLength
().
call
())
```
<a
name=
"argument-after-asterisk-must-be-an-iterable-not-nonetype"
></a>
gas required exceeds allowance
```
python
# Error text: ValueError: {'code': -32000, 'message': 'gas required exceeds allowance (8000000)'}
```
Tu transacción va a fallar.
This diff is collapsed.
Click to expand it.
bin/libbfa/__init__.py
+
96
−
36
View file @
57f3f69d
...
...
@@ -8,6 +8,7 @@ import web3.exceptions
import
web3.middleware
import
ecdsa
from
Crypto.Hash
import
keccak
import
eth_account
;
class
Bfa
:
...
...
@@ -19,9 +20,9 @@ class Bfa:
elif
'
HOME
'
in
os
.
environ
and
os
.
path
.
isdir
(
os
.
path
.
join
(
os
.
environ
[
'
HOME
'
],
'
bfa
'
)):
os
.
putenv
(
'
BFAHOME
'
,
os
.
path
.
join
(
os
.
environ
[
'
HOME
'
],
'
bfa
'
))
if
isinstance
(
provider
,
str
):
if
provider
in
[
'
prod
'
,
'
bfa2018
'
'
network
'
]:
if
provider
in
[
'
prod
'
,
'
bfa2018
'
,
'
network
'
,
''
]:
provider
=
web3
.
HTTPProvider
(
"
http://public.bfa.ar:8545/
"
)
elif
provider
in
[
'
test2network
'
,
'
test2
'
,
'
test
'
,
''
]:
elif
provider
in
[
'
test2network
'
,
'
test2
'
,
'
test
'
]:
provider
=
web3
.
HTTPProvider
(
"
http://public.test2.bfa.ar:8545/
"
)
elif
provider
.
startswith
(
'
http://
'
)
or
provider
.
startswith
(
'
https://
'
):
provider
=
web3
.
HTTPProvider
(
provider
)
...
...
@@ -35,20 +36,64 @@ class Bfa:
class
Account
:
def
__init__
(
self
,
accountname
:
str
,
passphrase
:
str
=
''
):
def
__init__
(
self
,
*
args
):
if
len
(
args
)
==
0
:
self
.
new
()
return
accountname
=
None
passphrase
=
''
if
len
(
args
)
>=
1
:
accountname
=
args
[
0
]
if
len
(
args
)
>=
2
:
passphrase
=
args
[
1
]
self
.
keyfile
=
None
self
.
private
key
=
None
self
.
key
=
None
self
.
unlock
(
accountname
,
passphrase
)
self
.
nonce
=
0
def
__repr__
(
self
)
->
str
:
return
str
(
dict
(
keyfile
=
self
.
keyfile
,
private
key
=
str
(
self
.
private
key
)))
return
str
(
dict
(
keyfile
=
self
.
keyfile
,
key
=
str
(
self
.
key
)))
def
__str__
(
self
)
->
str
:
return
self
.
walletaddress
()
return
self
.
address
def
new
(
self
):
acct
=
eth_account
.
Account
.
create
()
self
.
address
=
acct
.
address
self
.
key
=
acct
.
key
self
.
save
()
# print(acct.address)
# print(acct.key.hex())
return
acct
def
save
(
self
):
dir
=
None
if
os
.
getenv
(
'
BFANODEDIR
'
)
and
os
.
path
.
exists
(
os
.
path
.
join
(
os
.
environ
[
'
BFANODEDIR
'
],
'
keystore
'
)):
dir
=
os
.
path
.
join
(
os
.
environ
[
'
BFANODEDIR
'
],
'
keystore
'
)
elif
os
.
getenv
(
'
BFANETWORKDIR
'
)
and
os
.
path
.
exists
(
os
.
path
.
join
(
os
.
environ
[
'
BFANETWORKDIR
'
],
'
node
'
,
'
keystore
'
)):
dir
=
os
.
path
.
join
(
os
.
environ
[
'
BFANETWORKDIR
'
],
'
node
'
,
'
keystore
'
)
elif
os
.
getenv
(
'
BFAHOME
'
)
and
os
.
path
.
exists
(
os
.
path
.
join
(
os
.
environ
[
'
BFAHOME
'
],
'
network
'
,
'
node
'
,
'
keystore
'
)):
dir
=
os
.
path
.
join
(
os
.
environ
[
'
BFAHOME
'
],
'
network
'
,
'
node
'
,
'
keystore
'
)
elif
os
.
getenv
(
'
HOME
'
):
dir
=
os
.
path
.
join
(
os
.
environ
[
'
HOME
'
],
'
.ethereum
'
,
'
keystore
'
)
os
.
makedirs
(
dir
,
mode
=
0o700
,
exist_ok
=
True
)
else
:
raise
OSError
(
'
I have no idea where to save the file.
'
)
self
.
keyfile
=
os
.
path
.
join
(
dir
,
self
.
address
)
encrypted
=
eth_account
.
Account
.
encrypt
(
self
.
key
.
hex
(),
''
)
try
:
with
open
(
self
.
keyfile
,
'
w
'
,
encoding
=
'
utf=8
'
)
as
outfile
:
outfile
.
write
(
str
(
encrypted
).
replace
(
"'"
,
'"'
))
except
:
# os.remove(filename)
raise
pass
@staticmethod
def
findkeyfilesindirectories
(
pattern
:
str
):
def
findkeyfilesindirectories
(
**
kwargs
):
pattern
=
''
if
'
pattern
'
in
kwargs
:
pattern
=
kwargs
[
'
pattern
'
]
# Remove leading 0x if present
if
pattern
.
startswith
(
'
0x
'
):
pattern
=
pattern
[
2
:]
...
...
@@ -61,7 +106,7 @@ class Account:
elif
os
.
getenv
(
'
BFANETWORKDIR
'
):
wheretolook
+=
[
os
.
path
.
join
(
os
.
environ
[
'
BFANETWORKDIR
'
],
'
node
'
,
'
keystore
'
)]
elif
os
.
getenv
(
'
BFAHOME
'
):
wheretolook
+=
[
os
.
path
.
join
(
os
.
environ
[
'
BFA
NETWORKDIR
'
],
'
network
'
,
'
node
'
,
'
keystore
'
)]
wheretolook
+=
[
os
.
path
.
join
(
os
.
environ
[
'
BFA
HOME
'
],
'
network
'
,
'
node
'
,
'
keystore
'
)]
if
os
.
getenv
(
'
HOME
'
):
wheretolook
+=
[
os
.
path
.
join
(
os
.
environ
[
'
HOME
'
],
'
.ethereum
'
,
'
keystore
'
),
...
...
@@ -95,35 +140,33 @@ class Account:
if
os
.
path
.
isfile
(
accountname
):
self
.
keyfile
=
accountname
else
:
self
.
keyfile
=
self
.
findkeyfilesindirectories
(
accountname
)
self
.
keyfile
=
self
.
findkeyfilesindirectories
(
pattern
=
accountname
)
if
self
.
keyfile
is
None
:
raise
FileNotFoundError
(
'
The account was not found.
'
)
with
open
(
self
.
keyfile
)
as
fd
:
encrypted_key
=
fd
.
read
()
try
:
self
.
private
key
=
web3
.
Web3
().
eth
.
account
.
decrypt
(
encrypted_key
,
passphrase
)
self
.
key
=
web3
.
Web3
().
eth
.
account
.
decrypt
(
encrypted_key
,
passphrase
)
except
ValueError
as
exc
:
raise
ValueError
(
'
The passphrase given for the account is incorrect,
'
'
or the input file is not a valid key file.
'
'
The passphrase given for the account
in file {}
is incorrect,
'
'
or the input file is not a valid key file.
'
.
format
(
self
.
keyfile
)
)
from
exc
def
publickey
(
self
)
->
bytearray
:
key
=
ecdsa
.
SigningKey
.
from_string
(
self
.
privatekey
,
curve
=
ecdsa
.
SECP256k1
).
verifying_key
# returns bytestring
return
key
.
to_string
()
def
walletaddress
(
self
)
->
str
:
# ADDRESS
publickey
=
ecdsa
.
SigningKey
.
from_string
(
self
.
key
,
curve
=
ecdsa
.
SECP256k1
).
verifying_key
pkbytestring
=
publickey
.
to_string
()
# returns bytestring
ourhash
=
keccak
.
new
(
digest_bits
=
256
)
ourhash
.
update
(
self
.
publickey
()
)
ourhash
.
update
(
pkbytestring
)
digest
=
ourhash
.
hexdigest
()
return
web3
.
Web3
().
toChecksumAddress
(
'
0x
'
+
digest
[
-
40
:])
self
.
address
=
web3
.
Web3
().
toChecksumAddress
(
'
0x
'
+
digest
[
-
40
:])
def
transact
(
self
,
*
args
,
**
kwargs
):
w3
=
kwargs
.
get
(
'
web3
'
)
tx_details
=
self
.
calculate_tx_details
(
w3
,
*
args
,
**
kwargs
)
afunction
=
kwargs
.
get
(
'
function
'
)
tx_details
=
self
.
calculate_tx_details
(
w3
,
afunction
,
*
args
)
txobj
=
afunction
(
*
args
).
buildTransaction
(
tx_details
)
txobj
=
tx_details
if
afunction
:
txobj
=
afunction
(
*
args
).
buildTransaction
(
tx_details
)
receipt
=
self
.
txsignsendwait
(
w3
,
txobj
)
return
receipt
...
...
@@ -135,38 +178,53 @@ class Account:
return
receipt
def
signtx
(
self
,
tx
:
dict
):
signed
=
web3
.
Web3
().
eth
.
account
.
sign_transaction
(
tx
,
self
.
private
key
)
signed
=
web3
.
Web3
().
eth
.
account
.
sign_transaction
(
tx
,
self
.
key
)
return
signed
def
calculate_tx_details
(
self
,
w3
:
web3
.
Web3
,
afunction
,
*
args
)
->
dict
:
# if kwargs has extragas=50000 then we add that number to the amount
# of gas for the transaction
def
calculate_tx_details
(
self
,
w3
:
web3
.
Web3
,
*
args
,
**
kwargs
)
->
dict
:
# Nonce may have increase on the network without us noticing
# or past transactions may not yet have been mined (and a flooded
# txpool).
# This is a resonable fix (try not to send too many transactions)
# If you use waitForTransactionReceipt() between each transaction
# you will not have problems because of this.
self
.
nonce
=
max
(
self
.
nonce
,
w3
.
eth
.
getTransactionCount
(
self
.
walletaddress
()))
afunction
=
kwargs
.
get
(
'
function
'
)
self
.
nonce
=
max
(
self
.
nonce
,
w3
.
eth
.
getTransactionCount
(
self
.
address
))
# Set minimum gasPrice to 1 Gwei, but allow more if the network says so.
details
=
{
'
chainId
'
:
w3
.
eth
.
chain_id
(),
'
gasPrice
'
:
min
(
w3
.
toWei
(
'
1
'
,
'
gwei
'
),
w3
.
eth
.
gasPrice
),
'
nonce
'
:
self
.
nonce
,
'
from
'
:
self
.
wallet
address
()
,
'
from
'
:
self
.
address
,
}
for
kw
in
[
'
to
'
,
'
value
'
]:
val
=
kwargs
.
get
(
kw
)
if
val
is
not
None
:
details
[
kw
]
=
val
# Ask for balance, so we can tell it, in case we have an exception
balance
=
w3
.
eth
.
getBalance
(
self
.
wallet
address
()
)
balance
=
w3
.
eth
.
getBalance
(
self
.
address
)
try
:
# Ask a node how much gas it would cost to deploy
gas
=
afunction
(
*
args
).
estimateGas
(
details
)
if
afunction
:
# Ask a node how much gas it would cost to deploy
gas
=
afunction
(
*
args
).
estimateGas
(
details
)
else
:
gas
=
w3
.
eth
.
estimateGas
(
details
)
except
web3
.
exceptions
.
SolidityError
as
exc
:
raise
web3
.
exceptions
.
SolidityError
(
'
The Ethereum Virtual Machine probably did not like that.
'
)
from
exc
except
ValueError
as
exc
:
raise
ValueError
(
'
Your account may not have enough balance to work on this
'
'
network. It currently has {} wei.
'
'
Your transaction will fail. Maybe you are calling your
'
'
contract wrong or are not allowed to call the funcion
'
'
by a function modifier or
'
'
your account may not have enough balance to work on this
'
'
network. Your account balance is currently {} wei.
'
.
format
(
balance
))
from
exc
if
kwargs
.
get
(
'
extragas
'
)
is
not
None
:
gas
+=
kwargs
.
get
(
'
extragas
'
)
details
[
'
gas
'
]
=
gas
return
details
...
...
@@ -258,9 +316,11 @@ class CompiledContract:
with
open
(
'
{}.sol
'
.
format
(
self
.
name
),
'
r
'
)
as
infile
:
with
open
(
'
contract.sol
'
,
'
w
'
)
as
outfile
:
outfile
.
write
(
infile
.
read
())
solc
=
subprocess
.
run
(
self
.
dockerargs
(),
stdout
=
subprocess
.
PIPE
,
check
=
True
)
# Don't leave too much mess.
os
.
remove
(
'
contract.sol
'
)
try
:
solc
=
subprocess
.
run
(
self
.
dockerargs
(),
stdout
=
subprocess
.
PIPE
,
check
=
True
)
finally
:
# Don't leave too much mess.
os
.
remove
(
'
contract.sol
'
)
txt
=
solc
.
stdout
output
=
txt
.
decode
(
'
utf-8
'
)
self
.
json
=
json
.
loads
(
output
)
...
...
@@ -273,7 +333,7 @@ class CompiledContract:
except
FileNotFoundError
:
return
if
len
(
output
)
<
2
:
print
(
"
The JSON file is too
little
({} bytes read from {}).
"
.
format
(
len
(
output
),
filename
),
file
=
sys
.
stderr
)
print
(
"
The JSON file is too
small
({} bytes read from {}).
"
.
format
(
len
(
output
),
filename
),
file
=
sys
.
stderr
)
raise
NameError
try
:
self
.
json
=
json
.
loads
(
output
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment