# Built-in library

require load a module, such as local math = require'math'

Built-in modules include string, table, math, time, json, safemath, and require is not required when using

In addition, in non-contract mode, you can also use more built-in modules os, net, io, http, jsonrpc, etc.

Import library by default

# os module

os.clock() returns the number of clock seconds spent by the CPU executing the program

os.date(format, time) parameter timestamp is optional, if no current time is given for the time, return formatted string or table type time information

os.difftime(t2, t1) returns the difference between timestamps t2-t1

os.execute(command) execute system command command

os.exit(code, close) Exit the process, code is the error code, close means whether to exit the current virtual stack

os.getenv(varname) Get environment variables

os.remove(filename) delete file or empty folder

os.rename(oldname, newname) rename the file

os.setlocale(locale, category) Sets the time zone of the current program, category can choose the default value of all, indicating the scope of locale

os.time(table) table represents the time information table, the default is the current time information, return time stamp

os.tmpname() returns a temporary file name

# io module

io.close(file) Close the file

io.flush() flush the output buffer

io.input(file) open the file in read mode

io.lines(filename) reads the mode punch-in file and returns an iterator that traverses the lines in the file content

io.open(filename, mode) Open the file according to the specified mode, the optional values of mode are read mode'r', write mode'w', add mode'a', keep the old content update mode'r+', discard the old Content update mode'w+', keep the old content and only add the update mode'a+' at the end of the file, the default is'r'

io.read(read_mode) Read the content of the currently open input file and return. The parameter read_mode can have multiple optional values. The effects of different values are as follows:

"*all"     Read the entire file
"*line"    Read next line
"*number"  Read a number
<num>      Read a string with no more than <num> characters

io.seek(pos ?: int) Set or get the read and write position of the currently opened file. If the pos parameter is provided, the read and write position of the currently opened file is modified. If the pos parameter is not provided, the read and write position of the currently opened file is returned. position

io.write(content: string) Write the content of content to the currently opened file

E.g:

let io = require 'io';
let lines = io.lines("test/in.txt")     -- Read the file content, put each line of text content into lines (table type)
let text = table.concat(lines, ',')    
io.open("test/out.txt", "w")            -- Open the file in write mode (then the current open file is test/out.txt)
io.write(text)                          -- Write the text content to the currently open file (that is, test/out.txt)
let cur_pos = io.seek()                 -- The current read and write position of the open file is cur_pos
io.close()                              -- Close the currently open file

# net module

net.listen(address, port) TCP listens to the port port of the address, use '0.0.0.0' to listen to the port of all addresses, and return the TcpServer object net.connect(address, port) initiates a TCP connection

net.accept(server: TcpServer) tcp listener is blocked waiting for TCP client connection, return TcpSocket

net.accept_async(server: TcpServer, handler: Function) tcp monitors TCP client connections asynchronously. When a new connection appears, the socket function is used to trigger the handler function

net.start_io_loop(server: TcpServer) Start the TCP asynchronous server event loop. If you use accept_async asynchronous TCP service, you need to call this function later net.read(socket, count) read count bytes from the socket

net.read_until(socket, end: string) reads the byte stream from the socket until it encounters end, and the returned result contains end

net.write(socket, data) write byte stream or string to socket

net.close_socket(socket) close the socket connection

net.close_server(server) close TcpServer

net.shutdown() closes the entire IO event loop

E.g:

let server = net.listen("127.0.0.1", 3000)
while true do
    let ctx = net.accept(server)
    let data = net.read(ctx, 10)
    pprint(data)
end

# http module

http.listen(address: string, port: int) Listen for HTTP requests on the PORT port of the address

http.connect(address: string, port: int) connects to the HTTP server (generally does not need to be used directly)

http.request(method: string, url: string, body: string, headers: table) Send http request, return http reply

http.close(ctx) Close http request context

http.accept(server: HttpServer) Wait for http request, return http request context ctx

http.accept_async(server: HttpServer, handler: Function) monitors HTTP requests asynchronously. When a new HTTP request is received, the handler function is called using the HttpContext object as a parameter

http.start_io_loop(server: HttpServer) Start the HTTP asynchronous server event loop. If you use accept_async asynchronous TCP service, you need to call this function later

http.get_req_header(ctx, key: string) Get the value of key in the header information in http request

http.get_res_header(ctx, key: string) Get the value of key in header information in Http reply

http.get_req_http_method(ctx) Get HTTP method (string) in http request

http.get_req_path(ctx) Get the path part of http request

http.get_req_http_protocol Get HTTP protocol of HTTP request (string)

http.get_req_body(ctx) Get the body content in http request

http.set_res_header(ctx, key: string, value: string) Set the header information in the http reply

http.write_res_body(ctx, data: string) append write data to http reply

http.set_status(ctx, status_code: int, status_message: string) Set the status code and information in the http reply

http.get_status(ctx) Get the status code of http reply

http.get_status_message(ctx) Get status information (string) in http reply

http.get_res_body(ctx) Get the body content in http reply

http.finish_res(ctx) transmits the content of the http reply to the client, you must call this function to actually reply

The following is a simple example of using the blocking HTTP module (note that this is only a blocking API code example, it is not recommended to use it directly):

let http = require 'http'
let net = require 'net'

let res = http.request('GET', "http://www.gov.cn/", '', {
    Accept="text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    ["User-Agent"]="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
})
pprint(http.get_res_header(res, "Content-Length"))
pprint(http.get_res_body(res))
http.close(res)

let server = http.listen("0.0.0.0", 3000)

pprint("listening on 0.0.0.0:3000\n")

-- async api

let function handler(ctx)
    let net = require 'net'
    pprint("got new connection", ctx)
    -- pprint('get req body', http.get_req_body(ctx), '\n')
    net.write(ctx, "HTTP/1.1 200 OK\r\nContent-Type:text/html; utf-8\r\nContent-Length:5\r\n\r\nhello")
    net.close_socket(ctx)
end

net.accept_async(server, handler)
net.start_io_loop(server)

pprint("starting sync http server")

while true do
    let ctx = http.accept(server)
    pprint('get req body', http.get_req_body(ctx), '\n')
    http.write_res_body(ctx, "hello world")
    http.set_status(ctx, 200, 'OK')
    http.set_res_header(ctx, "Content-Type", "text/html; utf-8")
    http.finish_res(ctx)
    http.close(ctx)
end

Global variable table

# Some contract related APIs