Package: bitccl
BitCCL is aBitcartscripting language used for automating checkout flow and more.It is currently in alpha stage, being separated from themain Bitcart repository.ArchitechtureBitCCL is basically Python, but:Safe, with disabled import systemRobust, with many built-in functionsOptimized for running in Bitcart environmentLanguage file extension is.bccl.Runningpip install -r requirements.txt
./compiler example.bitcclBuilt-in functionsCurrent built-in functions list can be always seen infunctions.pyfile.Table of built-in functions:SignatureDescriptionReturn valueadd_event_listener(event, func)Adds event listenerfuncto be called wheneventis dispatchedNone@on(event)A decorator used for registering functions to be called wheneventis dispatched. Example:@on(ProductBought(1)) def func(): passWrapper functiondispatch_event(event, *args, **kwargs)Dispatchevent, optionally passing positional or named arguments to event handlersNonetemplate(name, data={})Render templatename, optionally passingdatato itTemplate text on success, empty string("") otherwisesend_email(to, subject, text)Sends email to email addressto, withsubjectandtext. Uses email server configuration fromconfig.jsonTrue on success, False otherwisepassword(length=SECURE_PASSWORD_LENGTH)Generate cryptographically unique password oflengthif provided, otherwise uses safe enough length.Generated passwordAlso a http client is available.To send http request with it, use:http.method(url)To send HTTP method (get, post, delete, patch, etc.) to url.
You can also optionally pass additional query parameters (params argument), request body data (data argument),
files (files argument), headers (headers argument), cookies (cookie argument) and more.Here is how the most complex request might look like:http.method(url,params={},headers={},cookies={},auth=None,allow_redirects=True,cert="",verify=True,timeout=5.0)All arguments except for url are optional.After sending a request, you can retrieve response data:If res is response got from callinghttp.method(...), then:res.textwill return text data from response (for example, html)res.contentwill return binary data from response (for example, file contents)res.json()will return json data from response (for example, when accessing different web APIs)Response status code can be got asres.status_code.For convenience, you are provided with http request codes to easily check if request is successful without remembering the numbers.For example,http_codes.OKis status code 200 (success).
So, to check if request has succeeded, you can check like so:res=http.get("https://example.com")ifres.status_code==http_codes.OK:print("Success")For additional information about built-in http client, you can read it's fulldocumentationAlso,Bitcart SDKis available to use.To access coins without xpub to get transaction, fiat rate or anything else not requiring a wallet, you can access each coin by
it's lowercase symbol, for example:print(btc.rate())print(ltc.rate())print(bch.rate())print(xrg.rate())print(bsty.rate())Note: running coins' commands require it's daemon running if you are not using BitCCL from Bitcart deployment.To perform operations requiring a wallet, use upper-case coin symbol, passing xpub/ypub/zpub/xprv/yprv/zprv/electrum seed in it:coin=BTC(xpub="my xpub")print(coin.balance())# or if using only once:print(BTC(xpub="my xpub").balance())Built-in eventsRefer toevents.md.It is generated automatically from BitCCL code.Plugin systemIf using BitCCL programmatically, you can extend it's execution context with plugins.Pass a list of plugin-like objects torunfunction, like so:frombitcclimportrunrun("print(x)",plugins=[TestPlugin()])Each plugin can be anything: class, object, module object, it must have two methods:startup()method returning dictionary, which will be used to update execution context with new variablesshutdown(context)method which should perform a clean-up of injected variables if neededHere's TestPlugin code from above's example:classTestPlugin:defstartup(self):return{"x":5}defshutdown(self,context):passHow does BitCCL secure the usersBitCCL usesRestrictedPythonproject with some modifications.Before executing arbitrary code, which could possibly be copied by a merchant from unknown source, we parse it into AST tree.Then, by AST transformation, we delete dangerous operations or replace them to non-existing names (for example getattr to_getattr_)The following code:x.foo=x.foo+x[0]is transformed to:_write(x).foo=_getattr(x,'foo')+_getitem(x,0)That way, our built-in functions have access to what they need, but user code is restricted.If some dangerous operations are found at AST transforming stage,CompilationRestrictedErroris raised with a list of errors.That way, in many cases code won't even be executed if it is dangerous.Afterwards, we execute the bytecode with a pretty limitedglobalsobject, with safer replacements for built-in functions.3 main points making it secure:Imports are disabled (import os; os.removedirs("/")or similar won't work)The main one: accessing magic attributes is disallowed, like__class__,__base__,__subclasses__and similar
It is not useful for user code, but opens many possible security holes
The worst example is this:print((1).__class__.__base__.__subclasses__())It could be used to access any class in your program, but accessing__class__and further is disallowed.
It also disallowed such cases astemplate.__globals__['os'].listdir('/')and many othersAlso, by providing a limited amount of globals, unsafe ones are excluded, so you are provided only with useful, but safe toolsContributingYou can contribute to BitCCL language by suggesting new built-in functions and events to be added, as well as any ideas for improving it.
Open anissueto suggest new featuresAlso see ourcontributing guidelines.Copyright and LicenseCopyright (C) 2020 MrNaif2018Licensed under theMIT license