@@ -491,6 +491,175 @@ and the arguments are ambiguous.
491491 1
492492
493493
494+ Enabling Strict Checks for Bytes Types
495+ --------------------------------------
496+
497+ By default, web3 is not very strict when it comes to hex and bytes values.
498+ A bytes type will take a hex string, a bytestring, or a regular python
499+ string that can be decoded as a hex.
500+ Additionally, if an abi specifies a byte size, but the value that gets
501+ passed in is less than the specified size, web3 will automatically pad the value.
502+ For example, if an abi specifies a type of ``bytes4 ``, web3 will handle all of the following values:
503+
504+ .. code-block :: python
505+
506+ - ' ' # valid - empty string less than 4 bytes and can be decoded as a hex string
507+ - ' 0x' # valid - empty hex string
508+ - b ' ' # valid - empty bytestring
509+ - b ' ab' # valid - less than 4 bytes
510+ - ' 0xab' # valid - hex string with less than 4 bytes
511+ - ' 1234' # valid - string that can be decoded as a hex string
512+ - ' 0x61626364' # valid - hex string with exactly 4 bytes
513+ - b ' 1234' # valid - bytestring with exactly 4 bytes
514+
515+ The following values will raise an error by default:
516+
517+ .. code-block :: python
518+
519+ - b ' abcde' # invalid - more than 4 bytes
520+ - ' 0x6162636423' # invalid - hex string with more than 4 bytes
521+ - 2 # invalid - wrong type
522+ - ' ah' # invalid - string not valid hex
523+
524+ However, you may want to be stricter with acceptable values for bytes types.
525+ For this you can use the ``enable_strict_bytes_type_checking `` method,
526+ which is available on the w3 instance. When the method is called, a new codec is
527+ instatntiated and any string that is not prefixed with
528+ ``0x `` will throw an error. Similarly, a bytestring that is less than the
529+ specified byte size will raise an error. Using the same ``bytes4 `` example:
530+
531+ .. code-block :: python
532+
533+ - ' 0x61626364' # valid - hex string with exactly 4 bytes
534+ - b ' 1234' # valid - bytestring with exactly 4 bytes
535+ - b ' ab' # invalid - less than 4 bytes
536+ - ' 0xab' # invalid - hex string with less than 4 bytes
537+ - ' ' # invalid - needs a 0x to be interpreted as hex
538+ - ' 1234' # invalid - needs a 0x to be interpreted as hex
539+ - b ' ' # invalid - less than 4 bytes
540+ - b ' abcde' # invalid - more than 4 bytes
541+ - ' 0x6162636423' # invalid - hex string with more than 4 bytes
542+ - 2 # invalid - wrong type
543+ - ' ah' # invalid - string not valid hex
544+
545+
546+ For example, the following contract code will generate the abi below and some bytecode:
547+
548+ .. testsetup ::
549+
550+ from web3 import Web3
551+ w3 = Web3(Web3.EthereumTesterProvider())
552+ bytecode = "608060405234801561001057600080fd5b506040516106103803806106108339810180604052602081101561003357600080fd5b81019080805164010000000081111561004b57600080fd5b8281019050602081018481111561006157600080fd5b815185602082028301116401000000008211171561007e57600080fd5b5050929190505050806000908051906020019061009c9291906100a3565b505061019c565b82805482825590600052602060002090600f0160109004810192821561015a5791602002820160005b8382111561012a57835183826101000a81548161ffff02191690837e010000000000000000000000000000000000000000000000000000000000009004021790555092602001926002016020816001010492830192600103026100cc565b80156101585782816101000a81549061ffff021916905560020160208160010104928301926001030261012a565b505b509050610167919061016b565b5090565b61019991905b8082111561019557600081816101000a81549061ffff021916905550600101610171565b5090565b90565b610465806101ab6000396000f3fe608060405260043610610051576000357c0100000000000000000000000000000000000000000000000000000000900480633b3230ee14610056578063d7c8a410146100e7578063dfe3136814610153575b600080fd5b34801561006257600080fd5b5061008f6004803603602081101561007957600080fd5b8101908080359060200190929190505050610218565b60405180827dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b3480156100f357600080fd5b506100fc61026c565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561013f578082015181840152602081019050610124565b505050509050019250505060405180910390f35b34801561015f57600080fd5b506102166004803603602081101561017657600080fd5b810190808035906020019064010000000081111561019357600080fd5b8201836020820111156101a557600080fd5b803590602001918460208302840111640100000000831117156101c757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050610326565b005b60008181548110151561022757fe5b9060005260206000209060109182820401919006600202915054906101000a90047e010000000000000000000000000000000000000000000000000000000000000281565b6060600080548060200260200160405190810160405280929190818152602001828054801561031c57602002820191906000526020600020906000905b82829054906101000a90047e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600201906020826001010492830192600103820291508084116102a95790505b5050505050905090565b806000908051906020019061033c929190610340565b5050565b82805482825590600052602060002090600f016010900481019282156103f75791602002820160005b838211156103c757835183826101000a81548161ffff02191690837e01000000000000000000000000000000000000000000000000000000000000900402179055509260200192600201602081600101049283019260010302610369565b80156103f55782816101000a81549061ffff02191690556002016020816001010492830192600103026103c7565b505b5090506104049190610408565b5090565b61043691905b8082111561043257600081816101000a81549061ffff02191690555060010161040e565b5090565b9056fea165627a7a72305820a8f9f1f4815c1eedfb8df31298a5cd13b198895de878871328b5d96296b69b4e0029"
553+
554+ .. code-block ::
555+
556+ >>> # pragma solidity >=0.4.22 <0.6.0;
557+ ...
558+ ... # contract ArraysContract {
559+ ... # bytes2[] public bytes2Value;
560+
561+ ... # constructor(bytes2[] memory _bytes2Value) public {
562+ ... # bytes2Value = _bytes2Value;
563+ ... # }
564+
565+ ... # function setBytes2Value(bytes2[] memory _bytes2Value) public {
566+ ... # bytes2Value = _bytes2Value;
567+ ... # }
568+
569+ ... # function getBytes2Value() public view returns (bytes2[] memory) {
570+ ... # return bytes2Value;
571+ ... # }
572+ ... # }
573+
574+ .. doctest ::
575+
576+ >>> abi = '''
577+ ... [
578+ ... {
579+ ... " constant" : true,
580+ ... " inputs" : [
581+ ... {
582+ ... " name" : " " ,
583+ ... " type" : " uint256"
584+ ... }
585+ ... ],
586+ ... " name" : " bytes2Value" ,
587+ ... " outputs" : [
588+ ... {
589+ ... " name" : " " ,
590+ ... " type" : " bytes2"
591+ ... }
592+ ... ],
593+ ... " payable" : false,
594+ ... " stateMutability" : " view" ,
595+ ... " type" : " function"
596+ ... },
597+ ... {
598+ ... " constant" : true,
599+ ... " inputs" : [],
600+ ... " name" : " getBytes2Value" ,
601+ ... " outputs" : [
602+ ... {
603+ ... " name" : " " ,
604+ ... " type" : " bytes2[]"
605+ ... }
606+ ... ],
607+ ... " payable" : false,
608+ ... " stateMutability" : " view" ,
609+ ... " type" : " function"
610+ ... },
611+ ... {
612+ ... " constant" : false,
613+ ... " inputs" : [
614+ ... {
615+ ... " name" : " _bytes2Value" ,
616+ ... " type" : " bytes2[]"
617+ ... }
618+ ... ],
619+ ... " name" : " setBytes2Value" ,
620+ ... " outputs" : [],
621+ ... " payable" : false,
622+ ... " stateMutability" : " nonpayable" ,
623+ ... " type" : " function"
624+ ... },
625+ ... {
626+ ... " inputs" : [
627+ ... {
628+ ... " name" : " _bytes2Value" ,
629+ ... " type" : " bytes2[]"
630+ ... }
631+ ... ],
632+ ... " payable" : false,
633+ ... " stateMutability" : " nonpayable" ,
634+ ... " type" : " constructor"
635+ ... }
636+ ... ]
637+ ... ''' .strip()
638+ >>> # bytecode = "6080..."
639+
640+ >>> ArraysContract = w3.eth.contract(abi = abi, bytecode = bytecode)
641+
642+ >>> tx_hash = ArraysContract.constructor([b ' b' ]).transact()
643+ >>> tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
644+
645+ >>> array_contract = w3.eth.contract(
646+ ... address= tx_receipt.contractAddress,
647+ ... abi= abi
648+ ... )
649+
650+ >>> array_contract.functions.getBytes2Value().call()
651+ [b'b\x00']
652+ >>> array_contract.functions.setBytes2Value([b ' a' ]).transact()
653+ HexBytes('0x39bc9a0bf5b8ec8e8115ccb20bf02f5570351a20a8fd774da91353f38535bec1')
654+ >>> array_contract.functions.getBytes2Value().call()
655+ [b'a\x00']
656+ >>> w3.enable_strict_bytes_type_checking()
657+ >>> array_contract.functions.setBytes2Value([b ' a' ]).transact()
658+ Traceback (most recent call last):
659+ ...
660+ ValidationError:
661+ Could not identify the intended function with name `setBytes2Value`
662+
494663Contract Functions
495664------------------
496665
0 commit comments