attestation
attestation copied to clipboard
DER data object decoder in Solidity
Produce the code represented in the ellipsis, which parses a data object.
pragma experimental ABIEncoderV2
struct Ticket {
uint match; // from 01 to 51
uint class; // club(0), lounge(1), silver(2), gold(3)
uint admission; // how many people can enter
}
function decodeTicket(bytes der) internal view returns(Ticket) {
[...]
}
function testDecoder() public view returns(bool) {
bytes constant der = "0x30090201010a0101020101";
Ticket ticket = decodeTicket(bytes der);
return ticket.match ==1 && ticket.class == 1 && ticket.admission == 01;
}
Testify that shows the bytes being correctly construted DER:
$ echo -n 30090201010a0101020101 | xxd -r -p | openssl asn1parse -inform DER -i
0:d=0 hl=2 l= 9 cons: SEQUENCE
2:d=1 hl=2 l= 1 prim: INTEGER :01
5:d=1 hl=2 l= 1 prim: ENUMERATED :01
8:d=1 hl=2 l= 1 prim: INTEGER :01
This is the python3 code to generate the DER-encoded data:
from pyasn1.codec.der import decoder, encoder
from pyasn1.type.univ import Sequence, OctetString, ObjectIdentifier, Integer, Enumerated
from pyasn1.type.namedtype import NamedTypes, NamedType
from pyasn1.type.namedval import NamedValues
class Class(Enumerated):
namedValues = NamedValues(
('The Club', 0), ('The Lounge', 1),
('Gold', 2), ('Silver', 3)
)
class Ticket(Sequence):
componentType = NamedTypes(
NamedType('match', Integer()),
NamedType('class', Class()),
NamedType('admission',Integer())
)
ticket = Ticket()
ticket['match'] = 1
ticket['class'] = 1
ticket['admission'] = 1
print(encoder.encode(ticket).hex())
As you may have noticed I made everything INTEGER
to make the work easier to start. Can't avoid the ENUMERATED
type though.
An earlier decoder written by James Brown is attached
with the following comments from him:
It has limitations in that any IA5 string decoded has to be 32 bytes or less, and it can only handle up to 40 translation objects. I can fix this in future.